fix: support scope-specific registry auth tokens#12392
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughRegistry authentication resolution is changed to prioritize package scope before falling back to registry URL, enabling different auth tokens for scopes sharing the same registry host. Both TypeScript and Rust stacks receive a new ChangesScoped Registry Auth
Sequence Diagram(s)sequenceDiagram
participant npmrc as .npmrc / env
participant ConfigReader as ConfigReader (TS)<br/>NpmrcAuth (Rust)
participant AuthHeaders as AuthHeaders<br/>Auth Lookup
participant Resolver as Package Resolver
participant Registry as Registry HTTP
npmrc->>ConfigReader: //npm.pkg.github.com/@orgA:_authToken=TOKEN_A<br/>//npm.pkg.github.com/@orgB:_authToken=TOKEN_B
ConfigReader->>ConfigReader: parse scope from registry key<br/>store nested [registry][`@orgA`] = TOKEN_A<br/>store nested [registry][`@orgB`] = TOKEN_B
ConfigReader->>AuthHeaders: build from nested creds<br/>via getAuthHeadersFromCreds
Resolver->>AuthHeaders: lookup_for_package(`@orgA/pkg`, registry)
AuthHeaders->>AuthHeaders: extract `@orgA` scope
AuthHeaders->>AuthHeaders: nerf-dart match<br/>scoped_by_scope[`@orgA`]
AuthHeaders-->>Resolver: Bearer TOKEN_A
Resolver->>Registry: GET /@orgA%2Fpkg<br/>Authorization: Bearer TOKEN_A
Registry-->>Resolver: 200 OK package metadata
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
✨ Finishing Touches🧪 Generate unit tests (beta)
|
Micro-Benchmark ResultsLinux |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #12392 +/- ##
==========================================
- Coverage 88.32% 88.13% -0.19%
==========================================
Files 298 300 +2
Lines 39034 39714 +680
==========================================
+ Hits 34477 35003 +526
- Misses 4557 4711 +154 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
4d5d4a2 to
dbfa165
Compare
Integrated-Benchmark Report (Linux)Each scenario reports direct installs and pnpr installs. Bencher consumes pacquet@HEAD and pnpr@HEAD. Scenario: Isolated linker: fresh restore, cold cache + cold store
BENCHMARK_REPORT.json{
"results": [
{
"command": "pacquet@HEAD",
"mean": 3.78666991188,
"stddev": 0.15363599317102547,
"median": 3.8242232127799998,
"user": 3.4433506799999996,
"system": 3.3088647799999995,
"min": 3.56663452128,
"max": 4.04545429628,
"times": [
4.04545429628,
3.65704975628,
3.9156075722800003,
3.84104918228,
3.80739724328,
3.8853070682800004,
3.59662595728,
3.56663452128,
3.69165792128,
3.85991560028
]
},
{
"command": "pacquet@main",
"mean": 3.61644489058,
"stddev": 0.11142797488832354,
"median": 3.5729575242800005,
"user": 3.5324500800000003,
"system": 3.2885356800000003,
"min": 3.49698444728,
"max": 3.86928715928,
"times": [
3.61767985628,
3.54751014028,
3.55233552828,
3.5729168172800003,
3.5465316392800004,
3.49698444728,
3.6496581592800004,
3.86928715928,
3.57299823128,
3.7385469272800003
]
},
{
"command": "pnpr@HEAD",
"mean": 2.09759097258,
"stddev": 0.10048444377201017,
"median": 2.0869875752800002,
"user": 2.59976698,
"system": 2.8903264799999997,
"min": 1.98196277328,
"max": 2.28829510228,
"times": [
2.1794901442800003,
2.01040292328,
1.98196277328,
1.98998790128,
2.15824891428,
2.09035018428,
2.28829510228,
2.17200742028,
2.08362496628,
2.02153939628
]
},
{
"command": "pnpr@main",
"mean": 2.0955489773800005,
"stddev": 0.10034489376852326,
"median": 2.0611273592800003,
"user": 2.6728827799999997,
"system": 2.8982791800000003,
"min": 1.98608657128,
"max": 2.27229614728,
"times": [
2.0090541552800003,
2.03064272128,
2.2319143292800003,
2.01588629328,
2.0916119972800002,
2.02852303528,
2.11811472628,
2.27229614728,
1.98608657128,
2.17135979728
]
}
]
}Scenario: Isolated linker: fresh restore, hot cache + hot store
BENCHMARK_REPORT.json{
"results": [
{
"command": "pacquet@HEAD",
"mean": 0.6156014294200001,
"stddev": 0.01099844172949568,
"median": 0.61958417212,
"user": 0.3549442399999999,
"system": 1.2740240599999997,
"min": 0.59626755762,
"max": 0.62630504762,
"times": [
0.62150494462,
0.61033497662,
0.61872394762,
0.59650396262,
0.6191306656200001,
0.62003767862,
0.6248470996200001,
0.59626755762,
0.62235841362,
0.62630504762
]
},
{
"command": "pacquet@main",
"mean": 0.63351064642,
"stddev": 0.09322916521462865,
"median": 0.59790899962,
"user": 0.35421623999999996,
"system": 1.2821966599999997,
"min": 0.58668091862,
"max": 0.89481370762,
"times": [
0.59715787662,
0.62424521062,
0.58970090362,
0.63483388862,
0.61967346562,
0.58668091862,
0.5954369526200001,
0.59866012262,
0.59390341762,
0.89481370762
]
},
{
"command": "pnpr@HEAD",
"mean": 0.68269245832,
"stddev": 0.059323800548062015,
"median": 0.66546146662,
"user": 0.36420723999999993,
"system": 1.3217705599999998,
"min": 0.6417796746200001,
"max": 0.84636624062,
"times": [
0.6965230036200001,
0.67558952362,
0.66378656762,
0.66713636562,
0.65846719062,
0.6534154736200001,
0.6417796746200001,
0.66756739462,
0.65629314862,
0.84636624062
]
},
{
"command": "pnpr@main",
"mean": 0.6455140236200001,
"stddev": 0.008744751271653134,
"median": 0.64529045362,
"user": 0.3783311399999999,
"system": 1.2844798599999998,
"min": 0.63437075462,
"max": 0.6644455286200001,
"times": [
0.6644455286200001,
0.64008331362,
0.63437075462,
0.63890146162,
0.6462331946200001,
0.64827388462,
0.63783173262,
0.64434771262,
0.64735860662,
0.65329404662
]
}
]
}Scenario: Isolated linker: fresh install, cold cache + cold store
BENCHMARK_REPORT.json{
"results": [
{
"command": "pacquet@HEAD",
"mean": 4.08107633264,
"stddev": 0.05469063275686689,
"median": 4.09859773224,
"user": 3.5957869799999997,
"system": 3.2595162599999994,
"min": 3.98553569924,
"max": 4.15362772224,
"times": [
3.98553569924,
4.12152436924,
4.10923529024,
4.04962596224,
4.11256939424,
4.15362772224,
4.08660494424,
4.09426962924,
3.9948444802400003,
4.10292583524
]
},
{
"command": "pacquet@main",
"mean": 4.111612447640001,
"stddev": 0.06517795709842235,
"median": 4.09389866874,
"user": 3.678760079999999,
"system": 3.2572165600000007,
"min": 4.0366410332400005,
"max": 4.26606296724,
"times": [
4.09485676624,
4.09244839024,
4.05495290524,
4.07628934524,
4.26606296724,
4.0366410332400005,
4.16759926124,
4.09294057124,
4.10985499424,
4.12447824224
]
},
{
"command": "pnpr@HEAD",
"mean": 2.11014812294,
"stddev": 0.09980658773359877,
"median": 2.06894321424,
"user": 2.4236724799999996,
"system": 2.83889026,
"min": 2.01889459724,
"max": 2.32880520024,
"times": [
2.11657109224,
2.15290402324,
2.06035510824,
2.05385681024,
2.0775313202400003,
2.32880520024,
2.04807189424,
2.02029785524,
2.22419332824,
2.01889459724
]
},
{
"command": "pnpr@main",
"mean": 2.1191709227400004,
"stddev": 0.12376192482317472,
"median": 2.0861327797399998,
"user": 2.48426268,
"system": 2.8284512600000005,
"min": 1.97473581124,
"max": 2.3500044942400002,
"times": [
2.09323574724,
2.10267718624,
2.0267392392400003,
1.99706289024,
2.27204601324,
2.07902981224,
2.3500044942400002,
2.2276321132400003,
1.97473581124,
2.06854592024
]
}
]
}Scenario: Isolated linker: fresh install, hot cache + hot store
BENCHMARK_REPORT.json{
"results": [
{
"command": "pacquet@HEAD",
"mean": 1.2566899398999998,
"stddev": 0.013981519372908134,
"median": 1.2536957754999998,
"user": 1.2394926599999998,
"system": 1.6545815400000001,
"min": 1.2412355075,
"max": 1.2793715074999998,
"times": [
1.2518033935,
1.2793715074999998,
1.2644721805,
1.2416216945,
1.2420424294999999,
1.2488381665,
1.2555881574999999,
1.2412355075,
1.2731648494999999,
1.2687615125
]
},
{
"command": "pacquet@main",
"mean": 1.2970911215,
"stddev": 0.05010995908356041,
"median": 1.284402849,
"user": 1.2578352599999998,
"system": 1.6896536400000002,
"min": 1.2665728085,
"max": 1.4359280895,
"times": [
1.2808008645,
1.3036375464999999,
1.2901601605,
1.2745745955,
1.4359280895,
1.2898074935,
1.2715656455,
1.2665728085,
1.2698591775,
1.2880048334999998
]
},
{
"command": "pnpr@HEAD",
"mean": 0.6489462253999999,
"stddev": 0.07579815775181901,
"median": 0.623438861,
"user": 0.3097473600000001,
"system": 1.24897004,
"min": 0.6131982755,
"max": 0.8637033615,
"times": [
0.6225641755,
0.6131982755,
0.6194470875,
0.6228971045,
0.6228892014999999,
0.8637033615,
0.6290733655,
0.6239806175,
0.6323211795,
0.6393878855
]
},
{
"command": "pnpr@main",
"mean": 0.6463695199000001,
"stddev": 0.08589197430288771,
"median": 0.620453649,
"user": 0.31771856000000004,
"system": 1.23373764,
"min": 0.6041197835,
"max": 0.8896080145,
"times": [
0.6041197835,
0.6207896185,
0.6205881515,
0.6203191465,
0.6085952845,
0.6265719685,
0.6197240555,
0.6352285395,
0.6181506365,
0.8896080145
]
}
]
}Scenario: Isolated linker: fresh install, cold cache + hot store
BENCHMARK_REPORT.json{
"results": [
{
"command": "pacquet@HEAD",
"mean": 2.97937998802,
"stddev": 0.03753497503455069,
"median": 2.9799811171199995,
"user": 1.69327972,
"system": 2.01678536,
"min": 2.94146395612,
"max": 3.06792862412,
"times": [
2.96049124712,
2.94146395612,
2.9726550221199997,
2.94327506012,
2.9873072121199997,
2.94553857812,
2.9893983831199997,
3.06792862412,
2.98945419512,
2.99628760212
]
},
{
"command": "pacquet@main",
"mean": 2.92682137202,
"stddev": 0.02874919690881723,
"median": 2.9297712251199997,
"user": 1.70567032,
"system": 1.88861006,
"min": 2.8877608741199996,
"max": 2.97219604812,
"times": [
2.97219604812,
2.8877608741199996,
2.92892301812,
2.9018596411199997,
2.9034586551199997,
2.9319008791199996,
2.89907101312,
2.96466208712,
2.9477620721199997,
2.93061943212
]
},
{
"command": "pnpr@HEAD",
"mean": 0.63539006012,
"stddev": 0.01190385940233323,
"median": 0.63545138062,
"user": 0.31880981999999997,
"system": 1.25183176,
"min": 0.62144890612,
"max": 0.65280939512,
"times": [
0.6404604181200001,
0.62751832512,
0.62215432512,
0.63155269512,
0.6467521581200001,
0.62261195512,
0.64924235712,
0.63935006612,
0.65280939512,
0.62144890612
]
},
{
"command": "pnpr@main",
"mean": 0.6352339171200001,
"stddev": 0.014142816340391268,
"median": 0.63491715362,
"user": 0.31029582,
"system": 1.24942006,
"min": 0.61712934312,
"max": 0.65093338712,
"times": [
0.6491256511200001,
0.6504123941200001,
0.6325996821200001,
0.64898037212,
0.61712934312,
0.6372346251200001,
0.6184412611200001,
0.65093338712,
0.6184264501200001,
0.62905600512
]
}
]
} |
|
| Branch | pr/12392 |
| Testbed | pacquet |
Click to view all benchmark results
| Benchmark | Latency | Benchmark Result milliseconds (ms) (Result Δ%) | Upper Boundary milliseconds (ms) (Limit %) |
|---|---|---|---|
| isolated-linker.fresh-install.cold-cache.cold-store | 📈 view plot 🚷 view threshold | 4,081.08 ms(-5.10%)Baseline: 4,300.33 ms | 5,160.39 ms (79.08%) |
| isolated-linker.fresh-install.cold-cache.hot-store | 📈 view plot 🚷 view threshold | 2,979.38 ms(+3.00%)Baseline: 2,892.52 ms | 3,471.02 ms (85.84%) |
| isolated-linker.fresh-install.hot-cache.hot-store | 📈 view plot 🚷 view threshold | 1,256.69 ms(+6.53%)Baseline: 1,179.63 ms | 1,415.56 ms (88.78%) |
| isolated-linker.fresh-restore.cold-cache.cold-store | 📈 view plot 🚷 view threshold | 3,786.67 ms(-16.58%)Baseline: 4,539.50 ms | 5,447.40 ms (69.51%) |
| isolated-linker.fresh-restore.hot-cache.hot-store | 📈 view plot 🚷 view threshold | 615.60 ms(-5.02%)Baseline: 648.15 ms | 777.78 ms (79.15%) |
|
| Branch | pr/12392 |
| Testbed | pnpr |
⚠️ WARNING: No Threshold found!Without a Threshold, no Alerts will ever be generated.
Click here to create a new Threshold
For more information, see the Threshold documentation.
To only post results if a Threshold exists, set the--ci-only-thresholdsflag.
Click to view all benchmark results
| Benchmark | Latency | milliseconds (ms) |
|---|---|---|
| isolated-linker.fresh-install.cold-cache.cold-store | 📈 view plot | 2,110.15 ms |
| isolated-linker.fresh-install.cold-cache.hot-store | 📈 view plot | 635.39 ms |
| isolated-linker.fresh-install.hot-cache.hot-store | 📈 view plot | 648.95 ms |
| isolated-linker.fresh-restore.cold-cache.cold-store | 📈 view plot | 2,097.59 ms |
| isolated-linker.fresh-restore.hot-cache.hot-store | 📈 view plot | 682.69 ms |
d8e9998 to
cc61e74
Compare
Code Review by Qodo
Context used 1. Pnpr v1 authHeaders break
|
PR Summary by QodoSupport scope-specific registry auth tokens across pnpm, pnpr, and pacquet WalkthroughsDescription• Store registry auth as per-registry, per-package-scope entries ("@" is default scope).
• Prefer scope auth for scoped packages across metadata, tarballs, and registry commands.
• Forward scoped auth to pnpr/pacquet as structured authHeaders[registryUri][scope].
Diagramgraph TD
A[".npmrc / auth.ini"] --> B["getNetworkConfigs()"] --> C["configByUri[uri][scope]"] --> D["createGetAuthHeaderByURI()"] --> E["npm resolver + verifier"]
D --> F["tarball fetcher"]
D --> G["registry + publish/stage"]
C --> H["pnpr + pacquet auth forwarding"]
High-Level AssessmentThe following are alternative approaches to this PR: 1. Keep legacy `creds` slot + add `scopedCreds` map
2. Encode scope only in nerf-darted URI keys (no nested scopes)
3. Resolve auth strictly via registry selection (no pkgName threading)
Recommendation: The PR’s approach (explicit per-registry, per-scope credentials with '@' as the default and pkgName-aware lookup) is the most robust and debuggable way to support multiple tokens on the same registry host. The main thing to watch is compatibility: ensure any remaining internal/third-party callers are updated for the new File ChangesEnhancement (9)
Bug fix (22)
Refactor (3)
Tests (27)
Documentation (1)
Other (1)
|
|
Code review by qodo was updated up to the latest commit cda8102 |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
releasing/commands/src/publish/publishPackedPkg.ts (1)
241-255:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPreserve package-scope creds for publish, not just the
@fallback.For scoped packages, this loop still only reads
entry[DEFAULT_REGISTRY_SCOPE], sopnpm publishwill ignore@orgA/@orgBcredentials when both scopes point at the same registry host and fall back to the registry-wide token instead.Suggested fix
let creds: Creds | undefined let tls: RegistryConfig['tls'] = {} + const scopedCredKey = registryName === 'default' + ? DEFAULT_REGISTRY_SCOPE + : registryName for (const registryConfigKey of allRegistryConfigKeys(initialRegistryConfigKey)) { const entry = configByUri[registryConfigKey] if (!entry) continue // Auth from longer path collectively overrides shorter path - creds ??= entry[DEFAULT_REGISTRY_SCOPE] + creds ??= entry[scopedCredKey] ?? entry[DEFAULT_REGISTRY_SCOPE] // TLS from longer path individually overrides shorter path tls = { ...entry.tls, ...tls } } const config: RegistryConfig = { tls } if (creds) { config[DEFAULT_REGISTRY_SCOPE] = creds }This conflicts with the PR objective of allowing different auth tokens per scope on the same registry host.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@releasing/commands/src/publish/publishPackedPkg.ts` around lines 241 - 255, The credential lookup in the loop only reads from entry[DEFAULT_REGISTRY_SCOPE], ignoring package-scoped credentials like `@orgA` or `@orgB`. Modify the credential assignment logic to read the package-specific scope credentials first before falling back to DEFAULT_REGISTRY_SCOPE. Extract the specific scope identifier from initialRegistryConfigKey (which contains the scoped package information) and use it to look up entry[specificScope] first, only using entry[DEFAULT_REGISTRY_SCOPE] as a fallback. This ensures that when multiple scopes point to the same registry host, each scope retains its own authentication token rather than all falling back to the default registry-wide token.
🧹 Nitpick comments (1)
pacquet/crates/config/src/npmrc_auth/tests.rs (1)
1-5: 💤 Low valueConsider reordering imports to follow standard Rust conventions.
Standard Rust style places
stdimports first, external crates second (alphabetically), and local imports (crate,super) last. The current order mixes these groups.📦 Suggested import order
-use super::{EnvVar, NpmrcAuth, RawCreds, base64_decode, base64_encode}; -use crate::Config; -use pacquet_network::{DEFAULT_REGISTRY_SCOPE, NoProxySetting}; -use pretty_assertions::assert_eq; -use std::path::Path; +use std::path::Path; + +use pacquet_network::{DEFAULT_REGISTRY_SCOPE, NoProxySetting}; +use pretty_assertions::assert_eq; + +use crate::Config; +use super::{EnvVar, NpmrcAuth, RawCreds, base64_decode, base64_encode};🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pacquet/crates/config/src/npmrc_auth/tests.rs` around lines 1 - 5, The imports in the test file do not follow standard Rust conventions for import ordering. Reorder the imports at the top of the file to place std library imports first (use std::path::Path), followed by external crates in alphabetical order (use pacquet_network and use pretty_assertions), and finally local imports (use crate and use super) last. This ensures the imports follow the standard Rust style guide.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@releasing/commands/src/publish/publishPackedPkg.ts`:
- Around line 241-255: The credential lookup in the loop only reads from
entry[DEFAULT_REGISTRY_SCOPE], ignoring package-scoped credentials like `@orgA` or
`@orgB`. Modify the credential assignment logic to read the package-specific scope
credentials first before falling back to DEFAULT_REGISTRY_SCOPE. Extract the
specific scope identifier from initialRegistryConfigKey (which contains the
scoped package information) and use it to look up entry[specificScope] first,
only using entry[DEFAULT_REGISTRY_SCOPE] as a fallback. This ensures that when
multiple scopes point to the same registry host, each scope retains its own
authentication token rather than all falling back to the default registry-wide
token.
---
Nitpick comments:
In `@pacquet/crates/config/src/npmrc_auth/tests.rs`:
- Around line 1-5: The imports in the test file do not follow standard Rust
conventions for import ordering. Reorder the imports at the top of the file to
place std library imports first (use std::path::Path), followed by external
crates in alphabetical order (use pacquet_network and use pretty_assertions),
and finally local imports (use crate and use super) last. This ensures the
imports follow the standard Rust style guide.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 85e533a0-f8bd-469f-b010-de2370aea018
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (52)
.changeset/scoped-registry-auth.mdconfig/reader/src/getNetworkConfigs.tsconfig/reader/test/getNetworkConfigs.test.tsconfig/reader/test/index.tscore/types/src/misc.tsdeps/compliance/commands/test/audit/index.tsfetching/tarball-fetcher/src/index.tsfetching/tarball-fetcher/src/remoteTarballFetcher.tsfetching/tarball-fetcher/test/fetch.tsfetching/types/src/index.tsinstalling/deps-installer/src/install/index.tsinstalling/deps-installer/test/install/auth.tsnetwork/auth-header/src/getAuthHeadersFromConfig.tsnetwork/auth-header/src/index.tsnetwork/auth-header/test/getAuthHeaderByURI.tsnetwork/auth-header/test/getAuthHeadersFromConfig.test.tspacquet/crates/cli/src/cli_args/install.rspacquet/crates/config/src/lib.rspacquet/crates/config/src/npmrc_auth.rspacquet/crates/config/src/npmrc_auth/tests.rspacquet/crates/network/src/auth.rspacquet/crates/network/src/auth/tests.rspacquet/crates/network/src/lib.rspacquet/crates/pnpr-client/Cargo.tomlpacquet/crates/pnpr-client/src/lib.rspacquet/crates/pnpr-client/tests/integration.rspacquet/crates/registry/src/package.rspacquet/crates/registry/src/package_version.rspacquet/crates/resolving-npm-resolver/src/fetch_attestation_published_at.rspacquet/crates/resolving-npm-resolver/src/fetch_full_metadata.rspacquet/crates/resolving-npm-resolver/src/fetch_full_metadata/tests.rspacquet/crates/resolving-npm-resolver/src/fetch_full_metadata_cached.rspacquet/crates/tarball/src/lib.rspacquet/crates/tarball/src/tests.rspnpm/src/switchCliVersion.test.tspnpm/src/syncEnvLockfile.test.tspnpr/client/src/resolveViaPnprServer.tspnpr/crates/pnpr/src/resolver.rspnpr/crates/pnpr/src/resolver/protocol.rsregistry-access/commands/test/deprecate.tsregistry-access/commands/test/dist-tag.tsregistry-access/commands/test/star.tsregistry-access/commands/test/unpublish.tsregistry-access/commands/test/whoami.tsreleasing/commands/src/publish/publishPackedPkg.tsreleasing/commands/test/publish/batchPublish.test.tsreleasing/commands/test/publish/publish.tsreleasing/commands/test/publish/recursivePublish.tsresolving/npm-resolver/src/createNpmResolutionVerifier.tsresolving/npm-resolver/src/index.tsresolving/npm-resolver/test/createNpmResolutionVerifier.test.tsresolving/npm-resolver/test/index.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: ubuntu-latest / Node.js 26.3.0 / Test
- GitHub Check: ubuntu-latest / Node.js 22.13.0 / Test
- GitHub Check: windows-latest / Node.js 22.13.0 / Test
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use Standard Style with trailing commas, prefer functions over classes, declare functions after they are used relying on hoisting, limit function arguments to two or three with options objects for additional parameters
Follow import order: standard libraries, external dependencies (sorted alphabetically), then relative imports
Use JSDoc for function contracts (preconditions, postconditions, edge cases, why it exists) not for re-narrating the body; do not record past implementation shape or refactor history in comments
Files:
fetching/types/src/index.tsfetching/tarball-fetcher/src/index.tscore/types/src/misc.tsreleasing/commands/test/publish/recursivePublish.tsregistry-access/commands/test/dist-tag.tsregistry-access/commands/test/unpublish.tsregistry-access/commands/test/deprecate.tspnpr/client/src/resolveViaPnprServer.tsreleasing/commands/test/publish/batchPublish.test.tsfetching/tarball-fetcher/test/fetch.tsregistry-access/commands/test/whoami.tsregistry-access/commands/test/star.tspnpm/src/syncEnvLockfile.test.tsresolving/npm-resolver/test/index.tsinstalling/deps-installer/src/install/index.tsresolving/npm-resolver/test/createNpmResolutionVerifier.test.tsdeps/compliance/commands/test/audit/index.tsnetwork/auth-header/test/getAuthHeadersFromConfig.test.tsreleasing/commands/src/publish/publishPackedPkg.tspnpm/src/switchCliVersion.test.tsfetching/tarball-fetcher/src/remoteTarballFetcher.tsreleasing/commands/test/publish/publish.tsconfig/reader/test/getNetworkConfigs.test.tsnetwork/auth-header/src/index.tsresolving/npm-resolver/src/index.tsnetwork/auth-header/test/getAuthHeaderByURI.tsinstalling/deps-installer/test/install/auth.tsnetwork/auth-header/src/getAuthHeadersFromConfig.tsconfig/reader/test/index.tsconfig/reader/src/getNetworkConfigs.tsresolving/npm-resolver/src/createNpmResolutionVerifier.ts
pacquet/**/*.rs
📄 CodeRabbit inference engine (pacquet/AGENTS.md)
pacquet/**/*.rs: Match how the same feature is implemented in the TypeScript pnpm CLI in pnpm/, pkg-manager/, resolving/, lockfile/, store/, fetching/, config/, hooks/, and other TypeScript workspaces — behavior, flags, defaults, error codes, file formats, and directory layout must match pnpm exactly
When porting a function that fires pnpm: events through globalLogger, logger.debug(...), or streamParser.write(...), mirror the call site, payload, and ordering so@pnpm/cli.default-reporterparses pacquet's NDJSON the same way it parses pnpm's. Follow the Reporter / log events convention for channel mapping, threading R: Reporter, emit-site placement, and recording-fake tests.
Prefer real fixtures using tempfile::TempDir, the mocked registry, or integration tests over dependency-injection seams for testing. Only use the DI seam (Host capability trait, Sys bounds, etc.) for branches real fixtures cannot cover: filesystem error kinds (PermissionDenied, ENOSPC), deterministic time, shared process-global state (env::set_var, set_current_dir, umask), or external-service happy paths (pnpm login 2FA, pnpm publish OIDC/provenance). Follow the eight principles and naming conventions (Sys, Host, Fs*, Clock, EnvVar) documented in CODE_STYLE_GUIDE.md.
Declare a newtype wrapper when porting code using branded string types from TypeScript pnpm. Do not collapse the brand into plain String or &str. Give the type its own struct so misuse is a type error.
If upstream always validates before construction of a branded string type, validate too. The Rust wrapper must construct only via TryFrom and/or FromStr. Do not provide an infallible public constructor that takes an arbitrary string.
If upstream never validates a branded string type, just brand for type-safety. Expose an infallible From and From<&str> when convenient. The type-safety win is the whole point, and no validator is needed.
If upstream occasionally constructs a branded string type without validatio...
Files:
pacquet/crates/config/src/lib.rspacquet/crates/network/src/lib.rspacquet/crates/resolving-npm-resolver/src/fetch_full_metadata/tests.rspacquet/crates/resolving-npm-resolver/src/fetch_full_metadata.rspacquet/crates/resolving-npm-resolver/src/fetch_full_metadata_cached.rspacquet/crates/tarball/src/tests.rspacquet/crates/cli/src/cli_args/install.rspacquet/crates/resolving-npm-resolver/src/fetch_attestation_published_at.rspacquet/crates/registry/src/package_version.rspacquet/crates/registry/src/package.rspacquet/crates/tarball/src/lib.rspacquet/crates/network/src/auth/tests.rspacquet/crates/pnpr-client/src/lib.rspacquet/crates/pnpr-client/tests/integration.rspacquet/crates/config/src/npmrc_auth/tests.rspacquet/crates/network/src/auth.rspacquet/crates/config/src/npmrc_auth.rs
pnpr/**/pnpr/**/*.rs
📄 CodeRabbit inference engine (pnpr/AGENTS.md)
pnpr/**/pnpr/**/*.rs: Follow the pacquet code-style guide (../pacquet/CODE_STYLE_GUIDE.md) for Rust-level conventions including imports, naming, ownership, and error handling
Follow the pacquet contributing guide (../pacquet/CONTRIBUTING.md) for test layout and Rust conventions
Files:
pnpr/crates/pnpr/src/resolver.rspnpr/crates/pnpr/src/resolver/protocol.rs
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
When checking if a caught error is an Error object in Jest, use util.types.isNativeError() instead of instanceof Error because instanceof checks can fail across VM realms
Files:
releasing/commands/test/publish/batchPublish.test.tspnpm/src/syncEnvLockfile.test.tsresolving/npm-resolver/test/createNpmResolutionVerifier.test.tsnetwork/auth-header/test/getAuthHeadersFromConfig.test.tspnpm/src/switchCliVersion.test.tsconfig/reader/test/getNetworkConfigs.test.ts
🧠 Learnings (10)
📚 Learning: 2026-05-26T21:01:06.666Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11966
File: .changeset/require-tarball-integrity.md:6-6
Timestamp: 2026-05-26T21:01:06.666Z
Learning: In pnpm lockfile-related release notes/docs (especially changeset markdown), preserve URL hostnames exactly as they appear in pnpm-lock.yaml tarball resolution entries—keep hosts like `codeload.github.com`, `bitbucket.org`, and `gitlab.com` in lowercase. Do not “correct” them to title-case/preserve brand capitalization (e.g., LanguageTool rules like `GITHUB` capitalization) because these are literal URL fragments, not platform brand names.
Applied to files:
.changeset/scoped-registry-auth.md
📚 Learning: 2026-05-14T09:04:00.133Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11622
File: resolving/npm-resolver/test/publishedBy.test.ts:350-354
Timestamp: 2026-05-14T09:04:00.133Z
Learning: In the pnpm/pnpm repository, ESLint is the authoritative style linter. Do not raise review findings for missing trailing commas in multiline function calls (e.g., `fs.writeFileSync(...)`) when this repo’s ESLint configuration does not report them and lint passes. Prefer deferring to the ESLint results for this specific trailing-comma rule rather than enforcing it manually in code review.
Applied to files:
fetching/types/src/index.tsfetching/tarball-fetcher/src/index.tscore/types/src/misc.tsreleasing/commands/test/publish/recursivePublish.tsregistry-access/commands/test/dist-tag.tsregistry-access/commands/test/unpublish.tsregistry-access/commands/test/deprecate.tspnpr/client/src/resolveViaPnprServer.tsreleasing/commands/test/publish/batchPublish.test.tsfetching/tarball-fetcher/test/fetch.tsregistry-access/commands/test/whoami.tsregistry-access/commands/test/star.tspnpm/src/syncEnvLockfile.test.tsresolving/npm-resolver/test/index.tsinstalling/deps-installer/src/install/index.tsresolving/npm-resolver/test/createNpmResolutionVerifier.test.tsdeps/compliance/commands/test/audit/index.tsnetwork/auth-header/test/getAuthHeadersFromConfig.test.tsreleasing/commands/src/publish/publishPackedPkg.tspnpm/src/switchCliVersion.test.tsfetching/tarball-fetcher/src/remoteTarballFetcher.tsreleasing/commands/test/publish/publish.tsconfig/reader/test/getNetworkConfigs.test.tsnetwork/auth-header/src/index.tsresolving/npm-resolver/src/index.tsnetwork/auth-header/test/getAuthHeaderByURI.tsinstalling/deps-installer/test/install/auth.tsnetwork/auth-header/src/getAuthHeadersFromConfig.tsconfig/reader/test/index.tsconfig/reader/src/getNetworkConfigs.tsresolving/npm-resolver/src/createNpmResolutionVerifier.ts
📚 Learning: 2026-06-05T13:47:26.046Z
Learnt from: vsumner
Repo: pnpm/pnpm PR: 12190
File: installing/deps-installer/src/install/index.ts:2337-2343
Timestamp: 2026-06-05T13:47:26.046Z
Learning: In the pnpm/pnpm codebase, `PnpmError` automatically prefixes `err.code` with `ERR_PNPM_` when you pass a code that does not already start with `ERR_PNPM_` (it normalizes `this.code` via `code.startsWith('ERR_PNPM_') ? code : `ERR_PNPM_${code}``). Therefore, during code review you should NOT flag `new PnpmError(...)` call sites for passing a bare error code (e.g., `new PnpmError('FROZEN_STORE_INCOMPATIBLE_WITH_PNPR', ...)`); the resulting `err.code` will still be `ERR_PNPM_FROZEN_STORE_INCOMPATIBLE_WITH_PNPR`.
Applied to files:
fetching/types/src/index.tsfetching/tarball-fetcher/src/index.tscore/types/src/misc.tsreleasing/commands/test/publish/recursivePublish.tsregistry-access/commands/test/dist-tag.tsregistry-access/commands/test/unpublish.tsregistry-access/commands/test/deprecate.tspnpr/client/src/resolveViaPnprServer.tsreleasing/commands/test/publish/batchPublish.test.tsfetching/tarball-fetcher/test/fetch.tsregistry-access/commands/test/whoami.tsregistry-access/commands/test/star.tspnpm/src/syncEnvLockfile.test.tsresolving/npm-resolver/test/index.tsinstalling/deps-installer/src/install/index.tsresolving/npm-resolver/test/createNpmResolutionVerifier.test.tsdeps/compliance/commands/test/audit/index.tsnetwork/auth-header/test/getAuthHeadersFromConfig.test.tsreleasing/commands/src/publish/publishPackedPkg.tspnpm/src/switchCliVersion.test.tsfetching/tarball-fetcher/src/remoteTarballFetcher.tsreleasing/commands/test/publish/publish.tsconfig/reader/test/getNetworkConfigs.test.tsnetwork/auth-header/src/index.tsresolving/npm-resolver/src/index.tsnetwork/auth-header/test/getAuthHeaderByURI.tsinstalling/deps-installer/test/install/auth.tsnetwork/auth-header/src/getAuthHeadersFromConfig.tsconfig/reader/test/index.tsconfig/reader/src/getNetworkConfigs.tsresolving/npm-resolver/src/createNpmResolutionVerifier.ts
📚 Learning: 2026-05-20T19:40:55.051Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11774
File: pacquet/crates/resolving-deps-resolver/src/resolve_peers.rs:0-0
Timestamp: 2026-05-20T19:40:55.051Z
Learning: In the pacquet Rust code, ensure the semver implementation uses the `node-semver` crate (not `nodejs-semver`). `node-semver`’s public API does not include a `satisfies_with_prerelease`-style method; prerelease-tolerant matching should be implemented inline by first calling `Range::satisfies`, and when it rejects a prerelease version, retry matching against a stripped `MAJOR.MINOR.PATCH` base of the prerelease version.
Applied to files:
pacquet/crates/config/src/lib.rspacquet/crates/network/src/lib.rspacquet/crates/resolving-npm-resolver/src/fetch_full_metadata/tests.rspacquet/crates/resolving-npm-resolver/src/fetch_full_metadata.rspacquet/crates/resolving-npm-resolver/src/fetch_full_metadata_cached.rspacquet/crates/tarball/src/tests.rspacquet/crates/cli/src/cli_args/install.rspacquet/crates/resolving-npm-resolver/src/fetch_attestation_published_at.rspacquet/crates/registry/src/package_version.rspacquet/crates/registry/src/package.rspacquet/crates/tarball/src/lib.rspacquet/crates/network/src/auth/tests.rspacquet/crates/pnpr-client/src/lib.rspacquet/crates/pnpr-client/tests/integration.rspacquet/crates/config/src/npmrc_auth/tests.rspacquet/crates/network/src/auth.rspacquet/crates/config/src/npmrc_auth.rs
📚 Learning: 2026-05-22T00:08:44.646Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11837
File: pacquet/crates/resolving-npm-resolver/src/pick_package.rs:33-51
Timestamp: 2026-05-22T00:08:44.646Z
Learning: In the pnpm/pnpm repo’s pacquet Rust crates, do not flag Unicode ellipsis characters (U+2026, `…`) in Rust doc comments (`///` / `/** */`) as a lint violation. The pacquet crate’s `dylint.toml` only enables `perfectionist::derive_ordering`, and the Dylint `unicode-ellipsis` rule is not enabled for this project—so `…` in doc comments is an intentional, repo-consistent style.
Applied to files:
pacquet/crates/config/src/lib.rspacquet/crates/network/src/lib.rspacquet/crates/resolving-npm-resolver/src/fetch_full_metadata/tests.rspacquet/crates/resolving-npm-resolver/src/fetch_full_metadata.rspacquet/crates/resolving-npm-resolver/src/fetch_full_metadata_cached.rspacquet/crates/tarball/src/tests.rspacquet/crates/cli/src/cli_args/install.rspacquet/crates/resolving-npm-resolver/src/fetch_attestation_published_at.rspacquet/crates/registry/src/package_version.rspacquet/crates/registry/src/package.rspacquet/crates/tarball/src/lib.rspacquet/crates/network/src/auth/tests.rspacquet/crates/pnpr-client/src/lib.rspacquet/crates/pnpr-client/tests/integration.rspacquet/crates/config/src/npmrc_auth/tests.rspacquet/crates/network/src/auth.rspacquet/crates/config/src/npmrc_auth.rs
📚 Learning: 2026-05-20T23:07:58.444Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11784
File: pacquet/crates/resolving-deps-resolver/src/hoist_peers.rs:120-133
Timestamp: 2026-05-20T23:07:58.444Z
Learning: When reviewing code in this pacquet Rust port, follow the upstream pnpm compatibility rule: only match pnpm’s behavior exactly. Do not propose review changes that intentionally deviate from pnpm’s documented/observed behavior, even if pnpm appears buggy. If you identify a real bug in pnpm behavior, the review should prioritize fixing it upstream in pnpm first, and avoid implementing a pnpm-behavior workaround here unless the same fix has already landed upstream.
Applied to files:
pacquet/crates/config/src/lib.rspacquet/crates/network/src/lib.rspacquet/crates/resolving-npm-resolver/src/fetch_full_metadata/tests.rspacquet/crates/resolving-npm-resolver/src/fetch_full_metadata.rspacquet/crates/resolving-npm-resolver/src/fetch_full_metadata_cached.rspacquet/crates/tarball/src/tests.rspacquet/crates/cli/src/cli_args/install.rspacquet/crates/resolving-npm-resolver/src/fetch_attestation_published_at.rspacquet/crates/registry/src/package_version.rspacquet/crates/registry/src/package.rspacquet/crates/tarball/src/lib.rspacquet/crates/network/src/auth/tests.rspacquet/crates/pnpr-client/src/lib.rspacquet/crates/pnpr-client/tests/integration.rspacquet/crates/config/src/npmrc_auth/tests.rspacquet/crates/network/src/auth.rspacquet/crates/config/src/npmrc_auth.rs
📚 Learning: 2026-06-06T18:58:37.156Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 12243
File: pacquet/crates/package-manager/src/install_package_by_snapshot.rs:319-322
Timestamp: 2026-06-06T18:58:37.156Z
Learning: When reviewing Rust code, do not assume `matches!(expr, Pattern(_))` will move out of `expr` if `Pattern(_)` contains no by-value bindings. `matches!` desugars to a `match` that auto-borrows the scrutinee for discrimination, so even if `expr` is a non-`Copy` value behind a shared reference (e.g., `&T`), the macro should not move-out of the borrowed data purely due to `matches!`. Treat `matches!(&expr, Pattern(_))` as a readability/clarity improvement, not a correctness requirement. Only flag potential move-out-of-borrow risks when the pattern includes by-value bindings that would require moving the matched value.
Applied to files:
pacquet/crates/config/src/lib.rspacquet/crates/network/src/lib.rspacquet/crates/resolving-npm-resolver/src/fetch_full_metadata/tests.rspacquet/crates/resolving-npm-resolver/src/fetch_full_metadata.rspacquet/crates/resolving-npm-resolver/src/fetch_full_metadata_cached.rspacquet/crates/tarball/src/tests.rspacquet/crates/cli/src/cli_args/install.rspnpr/crates/pnpr/src/resolver.rspacquet/crates/resolving-npm-resolver/src/fetch_attestation_published_at.rspacquet/crates/registry/src/package_version.rspacquet/crates/registry/src/package.rspnpr/crates/pnpr/src/resolver/protocol.rspacquet/crates/tarball/src/lib.rspacquet/crates/network/src/auth/tests.rspacquet/crates/pnpr-client/src/lib.rspacquet/crates/pnpr-client/tests/integration.rspacquet/crates/config/src/npmrc_auth/tests.rspacquet/crates/network/src/auth.rspacquet/crates/config/src/npmrc_auth.rs
📚 Learning: 2026-06-12T20:41:57.558Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 12364
File: pacquet/crates/package-manager/src/install/tests.rs:5717-5717
Timestamp: 2026-06-12T20:41:57.558Z
Learning: In the pnpm/pnpm Rust workspace (toolchain Rust 1.95.0), keep using `std::time::Duration::from_mins(...)` and `std::time::Duration::from_hours(...)` as-is. Do not flag these as invalid or suggest replacing them with `Duration::from_secs(...)`, because Clippy’s `clippy::duration_suboptimal_units` lint is denied by `-D warnings` in CI, and changing to seconds may trigger CI failures.
Applied to files:
pacquet/crates/config/src/lib.rspacquet/crates/network/src/lib.rspacquet/crates/resolving-npm-resolver/src/fetch_full_metadata/tests.rspacquet/crates/resolving-npm-resolver/src/fetch_full_metadata.rspacquet/crates/resolving-npm-resolver/src/fetch_full_metadata_cached.rspacquet/crates/tarball/src/tests.rspacquet/crates/cli/src/cli_args/install.rspnpr/crates/pnpr/src/resolver.rspacquet/crates/resolving-npm-resolver/src/fetch_attestation_published_at.rspacquet/crates/registry/src/package_version.rspacquet/crates/registry/src/package.rspnpr/crates/pnpr/src/resolver/protocol.rspacquet/crates/tarball/src/lib.rspacquet/crates/network/src/auth/tests.rspacquet/crates/pnpr-client/src/lib.rspacquet/crates/pnpr-client/tests/integration.rspacquet/crates/config/src/npmrc_auth/tests.rspacquet/crates/network/src/auth.rspacquet/crates/config/src/npmrc_auth.rs
📚 Learning: 2026-06-05T13:47:05.929Z
Learnt from: vsumner
Repo: pnpm/pnpm PR: 12190
File: installing/deps-installer/test/install/frozenStore.ts:2-17
Timestamp: 2026-06-05T13:47:05.929Z
Learning: In the pnpm/pnpm repository, the shared Jest preset keeps `injectGlobals` at its default (`true`), so `test` and `expect` are available as Jest globals. Therefore, reviewers should not flag (or treat as TypeScript/compilation errors) missing `import { test, expect } from 'jest/globals'` when a test file uses `test`/`expect` without importing them. Importing from `jest/globals` may still be used for consistency with sibling files, but it is not required for execution in this repo unless a Jest preset is explicitly configured with `injectGlobals: false`.
Applied to files:
releasing/commands/test/publish/recursivePublish.tsregistry-access/commands/test/dist-tag.tsregistry-access/commands/test/unpublish.tsregistry-access/commands/test/deprecate.tsreleasing/commands/test/publish/batchPublish.test.tsfetching/tarball-fetcher/test/fetch.tsregistry-access/commands/test/whoami.tsregistry-access/commands/test/star.tsresolving/npm-resolver/test/index.tsresolving/npm-resolver/test/createNpmResolutionVerifier.test.tsdeps/compliance/commands/test/audit/index.tsnetwork/auth-header/test/getAuthHeadersFromConfig.test.tsreleasing/commands/test/publish/publish.tsconfig/reader/test/getNetworkConfigs.test.tsnetwork/auth-header/test/getAuthHeaderByURI.tsinstalling/deps-installer/test/install/auth.tsconfig/reader/test/index.ts
📚 Learning: 2026-05-23T17:29:56.247Z
Learnt from: zkochan
Repo: pnpm/pnpm PR: 11878
File: resolving/npm-resolver/src/createNpmResolutionVerifier.ts:381-418
Timestamp: 2026-05-23T17:29:56.247Z
Learning: When reviewing the npm resolver code, note that `PackageMetaCache` is intentionally keyed only by `name` and `name:full` (no registry component). As a result, code that shares this cache (e.g., `createNpmResolutionVerifier.ts` via the shared `validateSharedMeta` guard) can prevent cross-package contamination by matching names, but it cannot distinguish two different registries that serve packages with the same name within a single install. Don’t flag (or attempt to fix) this as a local issue in the verifier alone—correctly distinguishing registries would require a coordinated change to the resolver cache key shape. (The Pacquet/Rust cache is already registry-qualified, unlike the npm-resolver cache.)
Applied to files:
resolving/npm-resolver/src/index.tsresolving/npm-resolver/src/createNpmResolutionVerifier.ts
🔇 Additional comments (49)
core/types/src/misc.ts (1)
31-32: LGTM!Also applies to: 54-57
fetching/types/src/index.ts (1)
23-27: LGTM!.changeset/scoped-registry-auth.md (1)
1-16: LGTM!config/reader/src/getNetworkConfigs.ts (1)
3-3: LGTM!Also applies to: 14-14, 25-28, 44-51, 77-81, 93-122
network/auth-header/src/getAuthHeadersFromConfig.ts (1)
4-56: LGTM!Also applies to: 58-61
network/auth-header/src/index.ts (1)
4-4: LGTM!Also applies to: 7-26, 35-96
pnpr/client/src/resolveViaPnprServer.ts (1)
11-12: LGTM!Also applies to: 40-45
pnpm/src/switchCliVersion.test.ts (1)
109-109: LGTM!Also applies to: 118-118, 171-171
registry-access/commands/test/star.ts (1)
10-10: LGTM!registry-access/commands/test/whoami.ts (1)
11-11: LGTM!resolving/npm-resolver/test/createNpmResolutionVerifier.test.ts (1)
78-111: LGTM!resolving/npm-resolver/test/index.ts (1)
323-346: LGTM!config/reader/test/getNetworkConfigs.test.ts (1)
91-92: LGTM!Also applies to: 105-111, 125-131, 144-145, 157-158, 164-183
config/reader/test/index.ts (1)
727-727: LGTM!Also applies to: 908-913, 1314-1315, 1332-1333, 1350-1351, 1376-1377, 1393-1394, 1409-1410, 1429-1430, 1449-1450
deps/compliance/commands/test/audit/index.ts (1)
283-283: LGTM!network/auth-header/test/getAuthHeadersFromConfig.test.ts (1)
6-7: LGTM!Also applies to: 34-43, 47-54, 58-65, 69-76, 80-86, 90-94, 95-129
installing/deps-installer/test/install/auth.ts (1)
24-24: LGTM!Also applies to: 40-40, 62-63, 83-84, 131-132, 179-180, 205-206
pnpm/src/syncEnvLockfile.test.ts (1)
150-150: LGTM!Also applies to: 160-160, 198-198
registry-access/commands/test/deprecate.ts (1)
16-20: LGTM!registry-access/commands/test/dist-tag.ts (1)
13-17: LGTM!registry-access/commands/test/unpublish.ts (1)
16-20: LGTM!releasing/commands/test/publish/batchPublish.test.ts (1)
87-89: LGTM!Also applies to: 210-212
releasing/commands/test/publish/publish.ts (1)
21-24: LGTM!Also applies to: 983-985, 1010-1012
releasing/commands/test/publish/recursivePublish.ts (1)
17-20: LGTM!pacquet/crates/network/src/auth.rs (1)
20-24: LGTM!Also applies to: 30-32, 39-42, 47-49, 85-85, 98-113, 115-172, 186-194, 213-223, 234-250, 278-309
pacquet/crates/network/src/lib.rs (1)
9-9: LGTM!pacquet/crates/resolving-npm-resolver/src/fetch_full_metadata.rs (1)
114-114: LGTM!pnpr/crates/pnpr/src/resolver/protocol.rs (1)
6-7: LGTM!Also applies to: 56-61
pacquet/crates/pnpr-client/Cargo.toml (1)
17-17: LGTM!pacquet/crates/network/src/auth/tests.rs (1)
1-1: LGTM!Also applies to: 136-234
pacquet/crates/resolving-npm-resolver/src/fetch_full_metadata/tests.rs (1)
101-153: LGTM!pacquet/crates/config/src/npmrc_auth.rs (1)
3-5: LGTM!Also applies to: 53-55, 203-204, 369-370, 515-538, 546-547, 601-606, 657-661, 696-703, 899-913
pacquet/crates/config/src/lib.rs (1)
1799-1799: LGTM!pacquet/crates/registry/src/package.rs (1)
132-132: LGTM!pacquet/crates/registry/src/package_version.rs (1)
270-270: LGTM!pacquet/crates/pnpr-client/src/lib.rs (1)
24-25: LGTM!Also applies to: 50-53, 92-92
pnpr/crates/pnpr/src/resolver.rs (1)
222-222: LGTM!Also applies to: 318-318
pacquet/crates/config/src/npmrc_auth/tests.rs (3)
36-48: LGTM!
149-168: LGTM!
170-192: LGTM!pacquet/crates/resolving-npm-resolver/src/fetch_full_metadata_cached.rs (1)
126-127: LGTM!pacquet/crates/resolving-npm-resolver/src/fetch_attestation_published_at.rs (1)
58-60: LGTM!pacquet/crates/cli/src/cli_args/install.rs (1)
603-605: LGTM!pacquet/crates/tarball/src/lib.rs (1)
1571-1572: No correctness issue found:for_url_with_packagecorrectly handles package_id shapes passed at these call sites.The
package_scope()function extracts the scope from package IDs like@fastify/error@3.3.0by splitting on the first/, which correctly isolates@fastifyfor scoped token lookup. Existing tests explicitly verify this behavior with the same@scope/name@versionformat used in the tarball and zip fetch paths.pacquet/crates/tarball/src/tests.rs (1)
1641-1681: LGTM!pacquet/crates/pnpr-client/tests/integration.rs (4)
17-17: LGTM!
55-61: LGTM!
125-125: LGTM!Also applies to: 135-136
157-160: LGTM!Also applies to: 381-384
|
Code review by qodo was updated up to the latest commit 10adc40 |
|
Code review by qodo was updated up to the latest commit 10adc40 |
|
Code review by qodo was updated up to the latest commit 6fb5b19 |
|
Code review by qodo was updated up to the latest commit a8f7949 |
|
Code review by qodo was updated up to the latest commit 719439c |
Summary
configByUri[registryUrl][scope], using@for registry-wide/default credentials and keepingtlsbeside the scope entries.@credentials.authHeaders[registryUrl][scope]instead of flattening scoped entries into URLs.Tests
pnpm --filter @pnpm/config.reader test test/getNetworkConfigs.test.ts --runInBand --watchman=falsepnpm --filter @pnpm/config.reader test test/index.ts --runInBand --watchman=false -t "project \\.npmrc does not expand env variables in auth values|package manager bootstrap registries ignore project workspace registries|unscoped credentials are pinned"pnpm --filter @pnpm/network.auth-header test test/getAuthHeadersFromConfig.test.ts test/getAuthHeaderByURI.ts --runInBand --watchman=falsepnpm --filter @pnpm/registry-access.commands test test/dist-tag.ts -t "dist-tag ls: should use package-scoped auth" --runInBand --watchman=falsepnpm --filter @pnpm/releasing.commands test test/stage.test.ts test/publish/publishConfigAccess.test.ts -t "stage list uses package-scoped auth|prefers package-scoped credentials" --runInBand --watchman=falsepnpm --filter @pnpm/types --filter @pnpm/config.reader --filter @pnpm/network.auth-header --filter @pnpm/installing.deps-installer --filter @pnpm/pnpr.client --filter @pnpm/releasing.commands run compilepnpm --filter @pnpm/registry-access.commands --filter @pnpm/deps.inspection.commands --filter @pnpm/releasing.commands run compilePNPM_REGISTRY_MOCK_PORT=7769 NODE_OPTIONS="$NODE_OPTIONS --experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169" pnpm --dir installing/deps-installer exec jest test/install/auth.ts --runInBand --watchman=falsepnpm --filter @pnpm/fetching.pick-fetcher test customFetch.ts --runInBandpnpm --filter @pnpm/fetching.tarball-fetcher test fetch.ts --runInBand --watchman=falsecargo test -p pacquet-network authcargo test -p pacquet-config npmrc_auth::tests::cargo test -p pacquet-pnpr-client credential --test integrationcargo check -p pacquet-clicargo clippy -p pacquet-network --all-targets -- -D warningscargo clippy -p pacquet-config --all-targets -- -D warningscargo clippy -p pacquet-config -p pacquet-network -p pacquet-pnpr-client -p pnpr --all-targets -- -D warningsRUSTFLAGS="-D warnings" cargo dylint --all -- --all-targets --workspacecargo fmt --all -- --checkpnpm exec cspell registry-access/commands/test/dist-tag.ts --no-progressgit diff --checkgit push --force-with-lease(includes pnpm bundle checks, workspace Rust clippy/docs/dylint, spellcheck, and metadata checks)Fixes #12390
Written by an agent (Codex, GPT-5).
Summary by CodeRabbit
@for registry-wide;@<scope>for scoped) instead of the previouscredswrapper.login --scopepersistence.