Comparing v12.0.1...v12.0.2 · npm/cli · GitHub
Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: npm/cli
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v12.0.1
Choose a base ref
...
head repository: npm/cli
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v12.0.2
Choose a head ref
  • 8 commits
  • 33 files changed
  • 6 contributors

Commits on Jul 10, 2026

  1. 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>
    reggi and Copilot authored Jul 10, 2026
    Configuration menu
    Copy the full SHA
    ddd50e9 View commit details
    Browse the repository at this point in the history
  2. 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>
    reggi and Copilot authored Jul 10, 2026
    Configuration menu
    Copy the full SHA
    7b1f6c1 View commit details
    Browse the repository at this point in the history

Commits on Jul 22, 2026

  1. 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>
    martinrrm and Copilot authored Jul 22, 2026
    Configuration menu
    Copy the full SHA
    882d0b2 View commit details
    Browse the repository at this point in the history

Commits on Jul 27, 2026

  1. 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
    manzoorwanijk authored Jul 27, 2026
    1 Configuration menu
    Copy the full SHA
    74eff59 View commit details
    Browse the repository at this point in the history
  2. 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)
    Hashim1999164 authored Jul 27, 2026
    Configuration menu
    Copy the full SHA
    9e17dc0 View commit details
    Browse the repository at this point in the history
  3. 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
    martinrrm and Copilot authored Jul 27, 2026
    Configuration menu
    Copy the full SHA
    ef6cfea View commit details
    Browse the repository at this point in the history
  4. 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
    martinrrm and Copilot authored Jul 27, 2026
    Configuration menu
    Copy the full SHA
    834408e View commit details
    Browse the repository at this point in the history

Commits on Jul 29, 2026

  1. chore: release 12.0.2

    github-actions[bot] authored and reggi committed Jul 29, 2026
    Configuration menu
    Copy the full SHA
    b888cc9 View commit details
    Browse the repository at this point in the history
Loading