Preserve special protocols (patch:, portal:, link:) when resolving catalog references #6965
+138
−9
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
closes: #6920
What's the problem this PR addresses?
When using the catalog plugin with TypeScript, installations would fail even with simple version specifications. For example:
{ "devDependencies": { "typescript": "catalog:" } }This would fail with:
Error: typescript@patch:typescript@npm%3A5.9.2#... isn't supported by any available resolverRoot cause: When resolving
typescript: 5.9.2from the catalog, Yarn automatically applies compatibility patches internally, resulting in apatch:protocol range in yarn.lock. However, the catalog plugin was incorrectly stripping or mangling this protocol information during resolution, causing the resolver to fail.This issue affects not just TypeScript, but any package that uses special protocols like
patch:,portal:, orlink:- whether explicitly specified in the catalog or automatically applied by Yarn.How did you fix it?
1. Added safe protocol preservation
Introduced
SAFE_PROTOCOLS_TO_ALWAYS_KEEPto explicitly preserve protocols that have special semantics:patch:- for applying patches to packages (including auto-applied compat patches)portal:- for local workspace referenceslink:- for symlinked packages2. Implemented
tryRoundTripRangefunctionThis function safely normalizes ranges while preserving protocol information:
npm:protocol when it's exactly the default protocol3. Fixed hook implementations
beforeWorkspacePacking: Now usesconvertToManifestRangeto strip internal params (like__locator) before applying the round-trip normalization, ensuring clean package.json files in published packagesreduceDependency: Returns the full range with protocol intact, as the resolver needs complete protocol information during dependency resolution4. Added comprehensive tests
Added test cases for all three safe protocols to ensure they are correctly preserved when resolving catalog references.
Testing
Tested with both explicit and implicit patch protocol usage:
Both cases now work correctly, with the patch protocol being properly preserved during resolution and installation.
Checklist