pnpm 12.10.1 → 12.11.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 CHANGED
@@ -1,5 +1,143 @@
1
1
  # pnpm
2
2
 
3
+ ## 12.11.1
4
+
5
+ This release fixes two ways `pnpm install` could fail, runs tools of any Rust release through `pnx`, and treats `registry.npmjs.com` as an alias of the npm registry.
6
+
7
+ ### Patch Changes
8
+
9
+ - `pnpm install` no longer fails when `packageManager` pins the pnpm version that is already running and the registry does not publish that version. pnpm warns and continues. A registry mirror that has not synced a release no longer blocks the commands of a project pinned to it.
10
+
11
+ - `pnpm install` no longer fails with `ERR_PNPM_CMD_SHIM_CHMOD` when `node_modules/.bin` holds a shim that another user created, if everyone can already execute it and it is not world-writable. This happens when several users share one checkout.
12
+
13
+ - `enable-modules-dir=false` (`enableModulesDir: false` through the Node.js addon) fetches the registry packages the host can install into the store again, as pnpm v10 did, while still writing nothing under `node_modules`. The setting exists for a `node_modules` that something else mounts from the store, such as a FUSE daemon, and that consumer no longer has to download each package on first access. A plain `--lockfile-only` run still fetches nothing.
14
+
15
+ - `pnpm pack` and `pnpm publish` no longer put `.npmignore` and `.gitignore` files in the tarball. A `files` entry that names one still ships it.
16
+
17
+ - pnpm now treats `https://registry.npmjs.com/` as an alias of `https://registry.npmjs.org/`. Registry requests, credentials, and trusted publishing use the canonical hostname.
18
+
19
+ - `pnx --package=rust@<channel> <tool>` runs a tool of that Rust release, for example `pnx --package=rust@nightly-2026-01-01 cargo build`. pnpm installs the release with the components and targets from `rust-toolchain.toml` and the target of each `--target` argument.
20
+
21
+ - `pnpm install` now links agent skills for more coding agents. It detects the agent from `ANTIGRAVITY_AGENT`, `COPILOT_AGENT`, `COPILOT_CLI`, `CODEX_THREAD_ID`, `CODEX_SANDBOX`, `AI_AGENT`, and `CLAUDE_CODE` [pnpm/tasks#116](https://github.com/pnpm/tasks/issues/116).
22
+
23
+ - When the registry rejects `pnpm stage publish`, the error message now starts with "Failed to stage package".
24
+
25
+ ## 12.11.0
26
+
27
+ This release adds Rust toolchain management, links the agent skills that dependencies ship, adds the `permissions` setting, and keeps the colors of streamed script output.
28
+
29
+ ### Minor Changes
30
+
31
+ - `pnpm install` now links the agent skills that direct dependencies ship under `skills/<name>/SKILL.md` into the project's agent skill directories, such as `.claude/skills`. A package's skills are linked only after you approve them with `pnpm approve`. The `skills.dirs` setting chooses the directories [pnpm/rfcs#35](https://github.com/pnpm/rfcs/pull/35).
32
+
33
+ Added the `permissions` setting, which records what each dependency may do. Its `build` capability works like `allowBuilds` and takes precedence over it. `pnpm approve-builds` writes to `permissions` when `pnpm-workspace.yaml` already has it, and to `allowBuilds` otherwise.
34
+
35
+ Added `pnpm permissions`, which lists the granted and denied permissions and the packages awaiting approval. `pnpm approve` reviews build scripts and agent skills in one prompt [pnpm/rfcs#36](https://github.com/pnpm/rfcs/pull/36).
36
+
37
+ - pnpm now installs and runs Rust toolchains.
38
+
39
+ - With `cargo.enabled`, `pnpm install` installs the toolchain named in `rust-toolchain.toml`. pnpm verifies the release signature, stores the toolchain once per machine, and links it into `.pnpm/rust`. `pnpm run` and `pnpm exec` put its `cargo` and `rustc` on the `PATH`.
40
+ - `pnpm add -g rust@<channel>` installs a toolchain globally. The `cargo` and `rustc` commands run it outside projects that pin their own. `pnpm update -g`, `pnpm ls -g`, and `pnpm remove -g` manage it like any global package.
41
+ - In a project, `pnpm add rust@<channel>` pins the toolchain in `rust-toolchain.toml`.
42
+ - `pnpm shim add rust` adds project-aware shims for `cargo`, `rustc`, and the other Rust tools. In a project with a `rust-toolchain.toml`, they run the toolchain the file names and install it on first use. Elsewhere, the next command of the same name on `PATH` runs, such as rustup's.
43
+
44
+ - `pnpm run` and `pnpm exec` now keep the colors of script output that they print under the project's name, such as with `--stream`. pnpm sets `FORCE_COLOR=1` for these scripts when its own output is in color, unless `FORCE_COLOR` is already set.
45
+
46
+ Script output is also rendered more cleanly:
47
+
48
+ - A line that a progress bar redraws with `\r` shows only its last state.
49
+ - Escape codes that move the cursor or clear the screen are dropped.
50
+ - Long colored lines are cut at the terminal width.
51
+ - `pnpm -r run` no longer garbles its live output when a script fails while other scripts are still running.
52
+
53
+ ### Patch Changes
54
+
55
+ #### Installing packages
56
+
57
+ - pnpm no longer panics with "unexpected error when polling the I/O driver" when it runs under QEMU user-mode emulation, such as a `linux/amd64` container on an Apple Silicon Mac [#16696](https://github.com/pnpm/pnpm/issues/16696).
58
+
59
+ - `pnpm view`, `pnpm update`, and other commands that read registry metadata now work behind proxies that end a response by closing the connection without a TLS `close_notify` alert [#16704](https://github.com/pnpm/pnpm/issues/16704).
60
+
61
+ - pnpm now switches to the version a project pins in `packageManager` or `devEngines.packageManager` even when `pnpm-workspace.yaml` has a setting the running pnpm cannot read, such as a `lockfile.includeResolutionSettings` section. If pnpm does not switch, it still reports that setting [#16675](https://github.com/pnpm/pnpm/issues/16675).
62
+
63
+ - When the `pnpm` package has to download its native binary on first run, it now uses the registry and credentials from `.npmrc` and from the `npm_config_registry` and `pnpm_config_registry` environment variables. `COREPACK_NPM_REGISTRY` still takes precedence. A project `.npmrc` is not read when `COREPACK_INTEGRITY_KEYS` turns off the signature check [#16655](https://github.com/pnpm/pnpm/issues/16655).
64
+
65
+ - `pnpm install` and `pnpm add --config` now apply `minimumReleaseAge` when they resolve a config dependency. A config dependency range resolves to the newest version that is old enough, so a later clean `pnpm install --frozen-lockfile` accepts the lockfile [#16660](https://github.com/pnpm/pnpm/issues/16660).
66
+
67
+ - `pnpm remove` with `catalogPrune` no longer removes catalog entries that `pnpm-lock.yaml` still records for workspace projects missing from disk. Before, a following frozen install failed with `ERR_PNPM_LOCKFILE_CONFIG_MISMATCH` [#16679](https://github.com/pnpm/pnpm/issues/16679).
68
+
69
+ - With `cargo.enabled`, `pnpm install` now writes the source replacement for vendored crates into `.pnpm/crates/config.toml` and includes it as optional from `.cargo/config.toml`. A checkout without `.pnpm` builds with plain Cargo [#16659](https://github.com/pnpm/pnpm/issues/16659).
70
+
71
+ - With `nodeLinker.type` set to `loaded`, Node.js now stops with `ERR_PNPM_LOADER_UNSUPPORTED_NODE` when it preloads the store loader on a version the loader cannot serve. The supported versions are `^24.18.0 || >=26.2.0`. On other versions, CommonJS packages imported from ESM failed with `Cannot find module` on their first relative `require()`.
72
+
73
+ - On Windows, `pnpm install` no longer fails with "The filename, directory name, or volume label syntax is incorrect" when a package contains a file whose name is invalid on Windows, such as `icon.svg?as=metadata.d.ts`. pnpm removes the invalid characters from the name and prints a warning that lists the renamed files.
74
+
75
+ - On Windows, hoisting no longer fails intermittently with link errors when a junction is created or replaced concurrently [pnpm/tasks#53](https://github.com/pnpm/tasks/issues/53).
76
+
77
+ #### Resolving dependencies
78
+
79
+ - `pnpm install --no-optional` now installs the peer dependencies a project declares when `autoInstallPeers` is on. The lockfile marked such a peer `optional: true` when another dependency had it as an optional peer.
80
+
81
+ - `pnpm install` and `pnpm dedupe` now link an optional peer to the workspace package that the workspace root depends on when the picked version matches it. They installed the registry package with the same name and version [#16706](https://github.com/pnpm/pnpm/issues/16706).
82
+
83
+ - Removal overrides such as `"debug>supports-color": "-"` now also apply to an optional peer that a package declares only in `peerDependenciesMeta` [#16681](https://github.com/pnpm/pnpm/issues/16681).
84
+
85
+ - `pnpm add` and other installs that re-resolve dependencies now keep the locked `devEngines.runtime` version while it still satisfies the declared range [#16764](https://github.com/pnpm/pnpm/issues/16764).
86
+
87
+ - `pnpm audit --fix update` now updates only the dependencies whose locked version is vulnerable [#14928](https://github.com/pnpm/pnpm/issues/14928).
88
+
89
+ - `pnpm outdated` and `pnpm update --interactive` now apply `overrides` before they look up the latest version. Before, a dependency overridden to an npm alias was compared with the latest version of the package the override replaces [#16719](https://github.com/pnpm/pnpm/issues/16719).
90
+
91
+ #### Patched dependencies
92
+
93
+ - Patches saved with CRLF line endings now apply, including a patch that creates or deletes a file. pnpm rejected the git headers of such a patch with `ERR_PNPM_INVALID_PATCH` and the message `invalid file mode: 100644` [#16641](https://github.com/pnpm/pnpm/issues/16641).
94
+
95
+ - A patch that changes a file's mode, such as adding or removing the executable bit, now applies the new mode on Unix [pnpm/tasks#110](https://github.com/pnpm/tasks/issues/110).
96
+
97
+ #### Injected dependencies and deploy
98
+
99
+ - With `sharedWorkspaceLockfile: false`, an injected workspace package installed in the same run as its dependent now holds only the files its `files` field selects. The copy also held other files of the project, such as `tsconfig.json` [#16683](https://github.com/pnpm/pnpm/issues/16683).
100
+
101
+ - A script listed in `syncInjectedDepsAfterScripts` no longer fails when it rewrites `package.json` while pnpm is copying its edits into the injected copies. The sync after the script now replaces a half-copied manifest.
102
+
103
+ - `pnpm deploy` with a shared lockfile no longer fails with `ERR_PNPM_LOCKFILE_CONFIG_MISMATCH` for `settings.dedupeInjectedDeps` or `settings.dedupePeerDependents` when `lockfile.includeResolutionSettings` is enabled. The deployed lockfile now records both settings as `false`, the values the deploy installs with.
104
+
105
+ - `pnpm deploy` now writes the dependencies in the deployed `package.json` sorted by name. It also sorts the `allowBuilds` entries in the deployed `pnpm-workspace.yaml`. Repeated deploys of the same lockfile now produce identical files [#16687](https://github.com/pnpm/pnpm/issues/16687).
106
+
107
+ #### Packing and publishing
108
+
109
+ - `pnpm pack` and `pnpm publish` now match `.npmignore` and `.gitignore` rules the way npm does. A negation such as `!lib/**` or `!lib/**/!(*.map)` re-includes files under a directory that an earlier `*` rule excluded [#16743](https://github.com/pnpm/pnpm/issues/16743).
110
+
111
+ - `pnpm pack` and `pnpm publish` no longer always include root files that merely start with `README`, `LICENSE`, or `LICENCE`, such as `README_INTERNAL.md`. Only `README`, `LICENSE`, `LICENCE`, and `COPYING`, with or without an extension, ship regardless of `files` and `.npmignore`, as in npm [#16753](https://github.com/pnpm/pnpm/issues/16753).
112
+
113
+ - `pnpm publish --provenance=false` and `--no-provenance` now turn off provenance under trusted publishing, so a package can be published from a self-hosted runner. Setting `provenance: false` in `pnpm-workspace.yaml` does the same [#16721](https://github.com/pnpm/pnpm/issues/16721).
114
+
115
+ #### Speed and resource use
116
+
117
+ - `pnpm install` hardlinks files from a group-writable or world-writable store again. pnpm copied every file from such a store into `node_modules` [#16677](https://github.com/pnpm/pnpm/issues/16677).
118
+
119
+ - A repeat `pnpm install` no longer imports patched packages and packages with build scripts again when nothing changed. Their builds no longer run again either. This happened when `recursiveInstall` was `false` or the project had a `file:` dependency [#16705](https://github.com/pnpm/pnpm/issues/16705).
120
+
121
+ - Verifying the lockfile against `trustPolicy` and `minimumReleaseAge` uses less memory. pnpm no longer keeps every published version's manifest of each checked package in memory until the install ends [#16656](https://github.com/pnpm/pnpm/issues/16656).
122
+
123
+ - `pnpm rebuild <pkg>` and `pnpm rebuild --pending` no longer read the manifest of every installed package to find build scripts. Only the selected packages are inspected and built. On a large `node_modules` served lazily, such as over a network or FUSE mount, this turned a rebuild of a few packages into a fetch of every package.
124
+
125
+ - `pnpm rebuild` no longer removes and recreates `node_modules` when the settings recorded in `node_modules/.modules.yaml` differ from the current configuration. The rebuild runs the build scripts against the installed packages as they are.
126
+
127
+ - `pnpm store prune` now compacts the store's `index.db` after removing package entries, so the file shrinks again [#16717](https://github.com/pnpm/pnpm/issues/16717).
128
+
129
+ #### Registry commands
130
+
131
+ - `pnpm whoami`, `pnpm bugs`, `pnpm docs`, `pnpm repo`, `pnpm star`, `pnpm unstar`, and `pnpm stars` now honor the `--registry` option.
132
+
133
+ - `--registry` now takes precedence over a scope's configured registry for scoped packages in `pnpm access`, `pnpm view`, `pnpm repo`, `pnpm star`, `pnpm unstar`, `pnpm owner`, `pnpm deprecate`, `pnpm undeprecate`, `pnpm unpublish`, `pnpm dist-tag`, `pnpm team`, and `pnpm stage`. Without `--registry`, `pnpm access` now sends a scoped package or scope to the registry configured for that scope.
134
+
135
+ - Registry commands now keep the path of a registry URL such as `https://example.com/npm/` when they build request URLs. This applies to `pnpm access`, `pnpm owner`, `pnpm ping`, `pnpm search`, `pnpm star`, `pnpm stars`, `pnpm team`, `pnpm unstar`, and `pnpm whoami`.
136
+
137
+ - `pnpm view` now honors the network retry settings.
138
+
139
+ - `pnpm repo` now fetches the repository URLs of several packages in parallel.
140
+
3
141
  ## 12.10.1
4
142
 
5
143
  This release fixes `pnpm install` failures after an `overrides` change and on a filtered frozen install with `catalogPrune`. It also fixes several bugs in the experimental `nodeLinker.type: loaded`, which now keeps its generated files in `node_modules`.
package/bin/pnpm.mjs CHANGED
@@ -17,12 +17,13 @@
17
17
  //
18
18
  // The download itself is `get-pnpm`, the package behind https://get.pnpm.io,
19
19
  // which already knows how to verify one; it travels in that same `dist/`
20
- // payload. What is left here is Corepack's environment, which it does not know:
21
- // where to download from, what credentials to use, and whose signature to trust.
20
+ // payload. What is left here is what it does not know: where to download from,
21
+ // what credentials to use, and whose signature to trust.
22
22
  import { Buffer } from 'node:buffer'
23
23
  import { spawnSync } from 'node:child_process'
24
24
  import console from 'node:console'
25
25
  import fs from 'node:fs'
26
+ import net from 'node:net'
26
27
  import os from 'node:os'
27
28
  import path from 'node:path'
28
29
  import process from 'node:process'
@@ -78,13 +79,13 @@ async function nativeBinary () {
78
79
  const { downloadPnpmExecutable } = await import(GET_PNPM).catch((err) => {
79
80
  fail(`This copy of the pnpm package is missing the downloader it needs: ${err.message}`)
80
81
  })
82
+ const signature = signaturePolicy()
81
83
  try {
82
84
  await downloadPnpmExecutable({
83
85
  version,
84
- registry: process.env.COREPACK_NPM_REGISTRY || DEFAULT_REGISTRY,
85
86
  destPath: DOWNLOADED_BINARY,
86
- headers: registryHeaders(),
87
- ...signaturePolicy(),
87
+ ...registryAccess({ readProjectNpmrc: signature.verifySignature !== false }),
88
+ ...signature,
88
89
  })
89
90
  } catch (err) {
90
91
  fail(`Could not download the pnpm ${version} binary: ${err.message}`)
@@ -93,22 +94,188 @@ async function nativeBinary () {
93
94
  }
94
95
 
95
96
  /**
96
- * Credentials for the registry, read the way Corepack reads its own. `get-pnpm`
97
- * keeps them on that registry's origin, so a download host it names never
98
- * receives them.
97
+ * The registry to download from, and the headers to send it. Corepack's
98
+ * `COREPACK_NPM_REGISTRY` wins. Otherwise npm's sources decide, highest first:
99
+ * the environment, the project `.npmrc`, the user `.npmrc`.
100
+ *
101
+ * The project `.npmrc` is read only with `readProjectNpmrc`, which the caller
102
+ * passes while the download is checked against npm's signature. The signature
103
+ * pins the bytes, so a repository picks only where they come from. Unchecked,
104
+ * it would pick the binary itself, which is kept next to this wrapper and run
105
+ * in every later project (GHSA-j2hc-m6cf-6jm8). `get-pnpm` keeps the headers on
106
+ * the registry's origin, so a download host it names never receives them.
99
107
  */
100
- function registryHeaders () {
108
+ function registryAccess ({ readProjectNpmrc }) {
109
+ const corepackRegistry = process.env.COREPACK_NPM_REGISTRY
110
+ if (corepackRegistry) {
111
+ return { registry: corepackRegistry, headers: corepackHeaders() }
112
+ }
113
+ const npmrc = readUserNpmrc()
114
+ if (readProjectNpmrc) {
115
+ Object.assign(npmrc, readNpmrc(path.join(projectDir(), '.npmrc'), projectEntry))
116
+ }
117
+ const registry = npmrc['@pnpm:registry'] || settingFromEnv('registry') || npmrc.registry
118
+ if (!registry) {
119
+ return { registry: DEFAULT_REGISTRY, headers: corepackHeaders() }
120
+ }
121
+ return { registry, headers: npmrcHeaders(npmrc, registry) }
122
+ }
123
+
124
+ /** Credentials for Corepack's registry, read the way Corepack reads its own. */
125
+ function corepackHeaders () {
101
126
  const { COREPACK_NPM_TOKEN, COREPACK_NPM_USERNAME, COREPACK_NPM_PASSWORD } = process.env
102
127
  if (COREPACK_NPM_TOKEN) {
103
128
  return { authorization: `Bearer ${COREPACK_NPM_TOKEN}` }
104
129
  }
105
130
  if (COREPACK_NPM_USERNAME && COREPACK_NPM_PASSWORD) {
106
- const credentials = Buffer.from(`${COREPACK_NPM_USERNAME}:${COREPACK_NPM_PASSWORD}`, 'utf8')
107
- return { authorization: `Basic ${credentials.toString('base64')}` }
131
+ return { authorization: `Basic ${base64(`${COREPACK_NPM_USERNAME}:${COREPACK_NPM_PASSWORD}`)}` }
108
132
  }
109
133
  return undefined
110
134
  }
111
135
 
136
+ function settingFromEnv (key) {
137
+ const upper = key.toUpperCase()
138
+ const { env } = process
139
+ return env[`pnpm_config_${key}`] || env[`PNPM_CONFIG_${upper}`] ||
140
+ env[`npm_config_${key}`] || env[`NPM_CONFIG_${upper}`] || undefined
141
+ }
142
+
143
+ /** The user `.npmrc`, with `${VAR}` placeholders expanded. */
144
+ function readUserNpmrc () {
145
+ return readNpmrc(
146
+ settingFromEnv('userconfig') || path.join(os.homedir(), '.npmrc'),
147
+ (key, value) => [expandEnv(key), expandEnv(value)]
148
+ )
149
+ }
150
+
151
+ /**
152
+ * A project `.npmrc` entry, which is not expanded. One with a `${VAR}`
153
+ * placeholder in a registry setting or a credential is dropped, as pnpm drops
154
+ * it: a repository must not route the user's environment to a registry.
155
+ */
156
+ function projectEntry (key, value, file) {
157
+ if (!key.includes('${') && !value.includes('${')) {
158
+ return [key, value]
159
+ }
160
+ if (key.startsWith('//') || key === 'registry' || key.endsWith(':registry')) {
161
+ console.error(`Ignored ${key} from ${file}: a project .npmrc cannot use environment variables in registry settings or credentials.`)
162
+ }
163
+ return undefined
164
+ }
165
+
166
+ /** Where pnpm reads the project `.npmrc`: the workspace root, or else the current directory. */
167
+ function projectDir () {
168
+ const cwd = process.cwd()
169
+ for (let dir = cwd; ; dir = path.dirname(dir)) {
170
+ if (fs.existsSync(path.join(dir, 'pnpm-workspace.yaml'))) {
171
+ return dir
172
+ }
173
+ if (path.dirname(dir) === dir) {
174
+ return cwd
175
+ }
176
+ }
177
+ }
178
+
179
+ /**
180
+ * The top-level settings of the `.npmrc` at `file`, each passed through
181
+ * `parseEntry`, which returns the `[key, value]` to keep or `undefined`.
182
+ */
183
+ function readNpmrc (file, parseEntry) {
184
+ const settings = Object.create(null)
185
+ let text
186
+ try {
187
+ text = fs.readFileSync(file, 'utf8')
188
+ } catch (err) {
189
+ if (err.code !== 'ENOENT' && err.code !== 'EISDIR') {
190
+ console.error(`Could not read ${file}, so its settings are not used: ${err.message}`)
191
+ }
192
+ return settings
193
+ }
194
+ for (const rawLine of text.split(/\r?\n/)) {
195
+ const line = rawLine.trim()
196
+ // Settings under a `[section]` are not top-level ones.
197
+ if (line.startsWith('[')) {
198
+ break
199
+ }
200
+ const separator = line.indexOf('=')
201
+ if (separator === -1 || line.startsWith(';') || line.startsWith('#')) {
202
+ continue
203
+ }
204
+ const entry = parseEntry(line.slice(0, separator).trim(), unquote(line.slice(separator + 1).trim()), file)
205
+ if (entry != null) {
206
+ settings[entry[0]] = entry[1]
207
+ }
208
+ }
209
+ return settings
210
+ }
211
+
212
+ function unquote (value) {
213
+ const quoted = value.length >= 2 && (value[0] === '"' || value[0] === "'") && value.at(-1) === value[0]
214
+ return quoted ? value.slice(1, -1) : value
215
+ }
216
+
217
+ function expandEnv (value) {
218
+ return value.replace(/\$\{([^${}]+)\}/g, (_, name) => process.env[name] ?? '')
219
+ }
220
+
221
+ /**
222
+ * The credentials the `.npmrc` holds for `registry`, looked up as pnpm looks
223
+ * them up for an `@pnpm` package: the `@pnpm` scope's own credentials first,
224
+ * then the registry-wide ones. Each is the longest `//host[:port]/path/`
225
+ * prefix of the registry URL that has any, then the same without the port.
226
+ * They are sent only over HTTPS or to the local machine.
227
+ */
228
+ function npmrcHeaders (npmrc, registry) {
229
+ const url = new URL(registry.endsWith('/') ? registry : `${registry}/`)
230
+ if (url.protocol !== 'https:' && !(url.protocol === 'http:' && isLoopback(url.hostname))) {
231
+ return undefined
232
+ }
233
+ const prefixes = []
234
+ for (const host of new Set([url.host, url.hostname])) {
235
+ for (let pathname = url.pathname; ; pathname = pathname.slice(0, pathname.lastIndexOf('/', pathname.length - 2) + 1)) {
236
+ prefixes.push(`//${host}${pathname}`)
237
+ if (pathname === '/') {
238
+ break
239
+ }
240
+ }
241
+ }
242
+ for (const scope of [':@pnpm', '']) {
243
+ for (const prefix of prefixes) {
244
+ const authorization = npmrcAuthorization(npmrc, `${prefix}${scope}`)
245
+ if (authorization != null) {
246
+ return { authorization }
247
+ }
248
+ }
249
+ }
250
+ return undefined
251
+ }
252
+
253
+ function isLoopback (hostname) {
254
+ return hostname === 'localhost' || hostname === '[::1]' ||
255
+ (net.isIPv4(hostname) && hostname.startsWith('127.'))
256
+ }
257
+
258
+ function npmrcAuthorization (npmrc, prefix) {
259
+ const token = npmrc[`${prefix}:_authToken`]
260
+ if (token) {
261
+ return `Bearer ${token}`
262
+ }
263
+ const auth = npmrc[`${prefix}:_auth`]
264
+ if (auth) {
265
+ return `Basic ${auth}`
266
+ }
267
+ const username = npmrc[`${prefix}:username`]
268
+ const password = npmrc[`${prefix}:_password`]
269
+ if (username && password) {
270
+ return `Basic ${base64(`${username}:${Buffer.from(password, 'base64').toString('utf8')}`)}`
271
+ }
272
+ return undefined
273
+ }
274
+
275
+ function base64 (text) {
276
+ return Buffer.from(text, 'utf8').toString('base64')
277
+ }
278
+
112
279
  /**
113
280
  * Whose signature over the download to trust, following `COREPACK_INTEGRITY_KEYS`
114
281
  * exactly as Corepack does: npm's own keys when it is unset, the keys it names
@@ -1,9 +1,9 @@
1
1
  {
2
- "lastValidatedTimestamp": 1791305376391,
2
+ "lastValidatedTimestamp": 1791546187431,
3
3
  "projects": {
4
4
  "/home/runner/_work/pnpm/pnpm/pnpm/npm/pnpm/temp-deploy": {
5
5
  "name": "pacquet",
6
- "version": "12.10.1",
6
+ "version": "12.11.1",
7
7
  "hasModulesDir": true
8
8
  }
9
9
  },
@@ -46,7 +46,7 @@
46
46
  "@pnpm/tabtab": "^0.5.4",
47
47
  "@pnpm/tgz-fixtures": "0.0.0",
48
48
  "@reflink/reflink": "0.1.19",
49
- "@rushstack/worker-pool": "0.7.29",
49
+ "@rushstack/worker-pool": "0.7.30",
50
50
  "@stylistic/eslint-plugin": "^5.10.0",
51
51
  "@tybys/wasm-util": "0.10.4",
52
52
  "@types/adm-zip": "^0.5.8",
@@ -88,7 +88,7 @@
88
88
  "@types/yarnpkg__lockfile": "^1.1.9",
89
89
  "@types/yauzl": "^3.4.0",
90
90
  "@types/zkochan__table": "npm:@types/table@6.3.2",
91
- "@typescript-eslint/utils": "^8.71.0",
91
+ "@typescript-eslint/utils": "^8.71.1",
92
92
  "@typescript/native-preview": "7.0.0-dev.20260707.2",
93
93
  "@webcontainer/api": "^1.6.4",
94
94
  "@yarnpkg/core": "4.9.1",
@@ -170,7 +170,7 @@
170
170
  "jest-diff": "30.4.1",
171
171
  "js-yaml": "npm:@zkochan/js-yaml@0.0.11",
172
172
  "json5": "^2.2.3",
173
- "keyv": "5.6.0",
173
+ "keyv": "6.1.0",
174
174
  "lcov-result-merger": "^6.0.0",
175
175
  "libnpmpublish": "^11.2.0",
176
176
  "load-json-file": "^7.0.1",
@@ -261,7 +261,7 @@
261
261
  "tree-kill": "^1.2.2",
262
262
  "ts-jest-resolver": "2.0.1",
263
263
  "typescript": "6.0.3",
264
- "typescript-eslint": "^8.71.0",
264
+ "typescript-eslint": "^8.71.1",
265
265
  "uid-number": "0.0.6",
266
266
  "undici": "^7.29.1",
267
267
  "unified": "^11.0.5",
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "./dist/node_modules/node-gyp/gyp/gyp"
10
10
  ]
11
11
  },
12
- "version": "12.10.1",
12
+ "version": "12.11.1",
13
13
  "description": "Fast, disk space efficient package manager",
14
14
  "keywords": [
15
15
  "pnpm",
@@ -46,20 +46,20 @@
46
46
  "THIRD-PARTY-NOTICES.md"
47
47
  ],
48
48
  "optionalDependencies": {
49
- "@pnpm/exe.win32-x64": "12.10.1",
50
- "@pnpm/exe.win32-arm64": "12.10.1",
51
- "@pnpm/exe.darwin-x64": "12.10.1",
52
- "@pnpm/exe.darwin-arm64": "12.10.1",
53
- "@pnpm/exe.linux-x64": "12.10.1",
54
- "@pnpm/exe.linux-arm64": "12.10.1",
55
- "@pnpm/exe.linux-riscv64": "12.10.1",
56
- "@pnpm/exe.linux-ppc64": "12.10.1",
57
- "@pnpm/exe.linux-s390x": "12.10.1",
58
- "@pnpm/exe.linux-x64-musl": "12.10.1",
59
- "@pnpm/exe.linux-arm64-musl": "12.10.1",
60
- "@pnpm/exe.freebsd-x64": "12.10.1",
61
- "@pnpm/exe.android-arm64": "12.10.1",
62
- "@pnpm/exe.android-x64": "12.10.1"
49
+ "@pnpm/exe.win32-x64": "12.11.1",
50
+ "@pnpm/exe.win32-arm64": "12.11.1",
51
+ "@pnpm/exe.darwin-x64": "12.11.1",
52
+ "@pnpm/exe.darwin-arm64": "12.11.1",
53
+ "@pnpm/exe.linux-x64": "12.11.1",
54
+ "@pnpm/exe.linux-arm64": "12.11.1",
55
+ "@pnpm/exe.linux-riscv64": "12.11.1",
56
+ "@pnpm/exe.linux-ppc64": "12.11.1",
57
+ "@pnpm/exe.linux-s390x": "12.11.1",
58
+ "@pnpm/exe.linux-x64-musl": "12.11.1",
59
+ "@pnpm/exe.linux-arm64-musl": "12.11.1",
60
+ "@pnpm/exe.freebsd-x64": "12.11.1",
61
+ "@pnpm/exe.android-arm64": "12.11.1",
62
+ "@pnpm/exe.android-x64": "12.11.1"
63
63
  },
64
64
  "scripts": {
65
65
  "preinstall": "node install.js",