Skip to content
This repository was archived by the owner on May 14, 2026. It is now read-only.
This repository was archived by the owner on May 14, 2026. It is now read-only.

Support proper auth #336

@KSXGitHub

Description

@KSXGitHub

Background

The npm registry and most pnpm-compatible private registries authenticate requests via credentials configured in .npmrc: per-registry bearer tokens (//registry.example.com/:_authToken=...), basic auth (_auth, or username + _password), and the always-auth setting. Credentials may be expanded from environment variables (e.g. ${NPM_TOKEN}). pnpm resolves these across global, user, project, and workspace .npmrc scopes and attaches the appropriate Authorization header to every registry request — metadata fetches and tarball downloads alike, even when the tarball is served from a different host than the metadata endpoint.

pacquet parses some auth fields in crates/npmrc/src/npmrc_auth.rs but does not currently apply them on outgoing requests in crates/network, crates/registry, or crates/tarball. As a result, pacquet install against private registries does not work the way pnpm install does.

Tasks

Examine pacquet's own codebase to see what auth handling already exists and where it stops short — config parsing, request construction in crates/network, and the metadata and tarball code paths in crates/registry and crates/tarball.

Research the pnpm codebase. Understand how .npmrc auth fields are parsed and merged across scopes, how a credential is selected for a given URL, how environment variable expansion works, how always-auth is honored, and how auth headers are attached to tarball hosts that differ from the metadata host.

Examine the accuracy of the claims in Background.

Implement this feature for pacquet install. Exactly as how pnpm implemented it. Match pnpm's auth field selection, URL matching, env expansion, and the error codes surfaced on 401/403.

Test coverage and the dependency injection pattern

After implementing the feature, check whether the new code introduces any uncovered coverage holes (for example, code paths that depend on environment variables, the global filesystem, or live network state — things that are awkward to exercise from a plain unit test).

If it does, refactor the new code to take its environment as injected parameters rather than reading globals directly, so the tests can drive every branch with local values. The dependency-injection pattern discussed in the comments below is the reference for how to do this in pacquet:

If the tests already cover every branch of the new code without DI (i.e. no new coverage holes), then the DI refactor is unnecessary and should be skipped.

Requirements

Mirror pnpm v11.

Carefully read and abide by the following files:

  1. AGENTS.md
  2. CONTRIBUTING.md
  3. CODE_STYLE_GUIDE.md
  4. plans/PORTING_GUIDE.md

If the porting guide needs to be updated, update it accordingly.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestrustPull requests that update Rust code

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions