Repository navigation
Comparing changes
Open a pull request
base repository: npm/cli
base: v12.0.1
head repository: npm/cli
compare: v12.0.2
- 8 commits
- 33 files changed
- 6 contributors
Commits on Jul 10, 2026
-
chore(arborist): add missing registry mock in bin links reify test (#…
…9746) The `bin links adding and removing` test in `workspaces/arborist/test/arborist/reify.js` reifies `rimraf@2.7.1` without setting up a mock registry. This adds `createRegistry(t, true)` so the test uses the mock registry instead of depending on the real one. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Configuration menu - View commit details
-
Copy full SHA for ddd50e9 - Browse repository at this point
Copy the full SHA ddd50e9View commit details -
chore: parse pack --json object output in node integration (#9747)
## Problem The `build nodejs` jobs in `Release Integration / publish` fail at `.github/workflows/node-integration.yml`: ``` node . pack --loglevel=silent --json | jq -r .[0].filename → jq: error (at <stdin>:9859): Cannot index object with number → Process completed with exit code 5 ``` As of #9247 (sync json output of pack and publish), `npm pack --json` no longer outputs an array. `logTar` now buffers `{ [tar.name]: tarball }`, so the output is an object keyed by package name: ```json { "npm": { "filename": "npm-12.0.1.tgz", ... } } ``` The workflow still parsed it with `.[0].filename`, which errors on an object. npm 12.0.x is the first release carrying this change, so the release integration only started breaking now. ## Fix Parse the filename from the object instead of an array index: ```diff -npmtarball="$(node . pack --loglevel=silent --json | jq -r .[0].filename)" +npmtarball="$(node . pack --loglevel=silent --json | jq -r 'to_entries[0].value.filename')" ``` Verified locally: returns `npm-12.0.1.tgz`. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Configuration menu - View commit details
-
Copy full SHA for 7b1f6c1 - Browse repository at this point
Copy the full SHA 7b1f6c1View commit details
Commits on Jul 22, 2026
-
fix(arborist): allow audit fix to install safe downgrades (#9761)
## What / Why `npm audit` can report that a fix is available through `npm audit fix` when the highest safe version inside the declared dependency range is older than the installed version. Arborist already selects that safe candidate using the advisory range, but `CanPlaceDep` rejects it because replacement candidates normally must be newer than the installed version. This causes `npm audit fix` to complete without applying the advertised remediation. ## How - Pass the existing audit report from `PlaceDep` into `CanPlaceDep` and recursive peer placement checks. - Permit an older candidate only when: - the installed node is vulnerable; - the candidate is not vulnerable; and - the candidate passes the existing replacement and peer dependency checks. - Preserve existing no-downgrade behavior for ordinary installs and updates. - Add synthetic, strictly mocked regressions covering: - compatible safe downgrades; - non-audit placement; - still-vulnerable candidates; - peer conflicts; - actual tree replacement; and - metavulnerability removal by pruning a vulnerable transitive dependency. This does not change audit reporting or `--force` behavior. Fixes outside declared dependency ranges still require `npm audit fix --force`. ## Testing - Focused Arborist placement and audit tests - npm command-level audit tests ## References Fixes #9557 Fixes #9718 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Configuration menu - View commit details
-
Copy full SHA for 882d0b2 - Browse repository at this point
Copy the full SHA 882d0b2View commit details
Commits on Jul 27, 2026
-
fix(arborist): avoid crash when peer back-off detaches a node (#9770)
Installing a package whose peers form a cycle with an already-installed optional peer could crash with `TypeError: Cannot read properties of null (reading 'explain')` instead of resolving or reporting a real conflict. A minimal trigger: `vite@8.1.4` declares an optional peer on `@vitejs/devtools`, `@vitejs/devtools` peers back on `vite`, so installing vite and then adding devtools crashes. The root cause is in `#loadPeerSet`. While resolving a package's peer edge through the parent's edge, the recursive `#nodeFromEdge` call can place a compatible peer that replaces and detaches the current node from the tree mid-iteration. The now-invalid edge then reached `#failPeerConflict`, whose `#explainPeerConflict` calls `node.resolve(edge.name).explain()` on the detached node. `resolve()` returns `null` for a node no longer in the tree, so `.explain()` threw. A detached node has been superseded by a compatible peer, so there is no real conflict to report. The fix adds a guard that stops processing when the node has been detached, right before `#failPeerConflict`, mirroring the existing top-of-loop detachment check. This lets the install complete by keeping the compatible peer that replaced the node (for the reproduction, `@vitejs/devtools` backs off to a version that satisfies vite's optional peer range) rather than crashing or raising a spurious `ERESOLVE`. ## References Fixes #5222 Closes #4787
1Configuration menu - View commit details
-
Copy full SHA for 74eff59 - Browse repository at this point
Copy the full SHA 74eff59View commit details -
docs: clarify npm 12 unknown-config breaking change in changelogs (#9805
) ## Summary Fixes #9802. Before the npm 12 stable cut, #9729 restored warn-by-default for unknown `.npmrc` keys (with `strict-npmrc` to opt into errors). #9733 updated the `12.0.0-pre.1` changelog bullet to match, but the aggregated stable `12.0.0` / `@npmcli/config@11.0.0` breaking-change notes (and the config package's `pre.1` note) still said unknown `.npmrc` configs throw. That stale line also shipped in the published [v12.0.0 GitHub release notes](https://github.com/npm/cli/releases/tag/v12.0.0). This aligns those changelog bullets with the corrected wording: > unknown CLI flags, abbreviated flags, and single-hyphen multi-char shorthands now throw instead of warning. (Unknown `.npmrc` configs still warn by default; opt into erroring with the new `strict-npmrc` config.) Maintainers may also want to refresh the published `v12.0.0` release body to match; that cannot be updated via this PR alone. ## References - #9729 (warn instead of error on unknown `.npmrc` configs) - #9733 (clarified the `pre.1` changelog note)
Configuration menu - View commit details
-
Copy full SHA for 9e17dc0 - Browse repository at this point
Copy the full SHA 9e17dc0View commit details -
fix(owner): use scoped registry for user lookup (#9786)
## Summary Ensure `npm owner add` and `npm owner rm` resolve users from the same registry used for the target package. The user lookup now receives the package `spec`, allowing `npm-registry-fetch` to honor scoped registry configuration instead of falling back to the global registry. ## Testing Added regression coverage for split global/scoped registry configurations, including: - Preventing substitution of the user added as an owner. - Preventing removal of an unintended existing owner. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1e1231bc-474e-4a27-8b78-242366f48e19
Configuration menu - View commit details
-
Copy full SHA for ef6cfea - Browse repository at this point
Copy the full SHA ef6cfeaView commit details -
fix(pack): honor min-release-age-exclude (#9760)
Make `npm pack` honor `min-release-age-exclude` when resolving packages from a registry. Given: ```ini min-release-age=7 min-release-age-exclude=@myscope/* ``` `npm pack @myscope/some-package@1.2.3` incorrectly failed with ETARGET when the package was newer than seven days, despite matching the exclusion. Root cause `min-release-age` is flattened into the `before` option consumed by `pacote` . However, `pacote` does not interpret `min-release-age-exclude` ; callers must remove before for matching packages. `npm pack` performs two manifest resolutions: 1. Directly through `pacote.manifest` 2. Internally through `libnpmpack` Both resolutions received the unmodified `before` option, so the exclusion was never applied. Fix Derive effective options for each package spec using the existing Arborist release-age helpers: • Clear `before` when the package matches `min-release-age-exclude` • Preserve the cutoff for nonmatching packages • Pass the same effective options to both manifest resolutions Using the alias target prevents an excluded alias name from disabling the release-age policy for an unrelated package. Test coverage Added regression coverage confirming that: • A recently published scoped package matching an exclusion glob can be packed • An excluded alias name does not exempt its non-excluded registry target The original scenario was also reproduced against a local registry: it failed with `ETARGET` before this change and successfully produced the tarball afterward. References Fixes #9759 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: dec204b6-ad66-45a5-8228-831e306f6ba6
Configuration menu - View commit details
-
Copy full SHA for 834408e - Browse repository at this point
Copy the full SHA 834408eView commit details
Commits on Jul 29, 2026
-
Configuration menu - View commit details
-
Copy full SHA for b888cc9 - Browse repository at this point
Copy the full SHA b888cc9View commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff v12.0.1...v12.0.2
