Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .yarn/versions/f352ecbe.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
releases:
"@yarnpkg/cli": patch
"@yarnpkg/plugin-catalog": patch

declined:
- "@yarnpkg/plugin-compat"
- "@yarnpkg/plugin-constraints"
- "@yarnpkg/plugin-dlx"
- "@yarnpkg/plugin-essentials"
- "@yarnpkg/plugin-init"
- "@yarnpkg/plugin-interactive-tools"
- "@yarnpkg/plugin-nm"
- "@yarnpkg/plugin-npm-cli"
- "@yarnpkg/plugin-pack"
- "@yarnpkg/plugin-patch"
- "@yarnpkg/plugin-pnp"
- "@yarnpkg/plugin-pnpm"
- "@yarnpkg/plugin-stage"
- "@yarnpkg/plugin-typescript"
- "@yarnpkg/plugin-version"
- "@yarnpkg/plugin-workspace-tools"
- "@yarnpkg/builder"
- "@yarnpkg/core"
- "@yarnpkg/doctor"
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,26 @@ describe(`Features`, () => {
),
);

test(
`it should throw an error when protocol in catalog isn't supported by any resolver`,
makeTemporaryEnv(
{
dependencies: {
[`no-deps`]: `catalog:`,
},
},
async ({path, run, source}) => {
await yarn.writeConfiguration(path, {
catalog: {
[`no-deps`]: `unknown-protocol:2.0.0`,
},
});

await expect(run(`install`)).rejects.toThrow();
},
),
);

test(
`it should work with file: protocol ranges in catalogs`,
makeTemporaryEnv(
Expand Down
4 changes: 4 additions & 0 deletions packages/plugin-catalog/sources/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ export const resolveDescriptorFromCatalog = (project: Project, dependency: Descr
structUtils.makeDescriptor(dependency, resolvedRange),
);

// If the descriptor isn't supported by any available resolver, return it as is
if (!resolver.supportsDescriptor(normalizedDescriptor, resolveOptions))
return normalizedDescriptor;

// Bind the descriptor to the project's top level workspace (which should match the project root),
// addressing issues with relative file paths when using `file:` protocol
const boundDescriptor = resolver.bindDescriptor(normalizedDescriptor, project.topLevelWorkspace.anchoredLocator, resolveOptions);
Expand Down
20 changes: 20 additions & 0 deletions packages/plugin-catalog/tests/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ describe(`utils`, () => {
// Create mock resolver with bindDescriptor method
mockResolver = {
bindDescriptor: jest.fn(descriptor => descriptor),
supportsDescriptor: jest.fn(() => true),
} as any;

resolveOptions = {
Expand Down Expand Up @@ -141,6 +142,25 @@ describe(`utils`, () => {
expect(structUtils.stringifyIdent(resolved)).toBe(`lodash`);
});

it(`should not resolve descriptor if it isn't supported by any resolver`, () => {
const catalog = new Map([
[`react`, `custom:^18.0.0`],
]);
configuration.values.set(`catalog`, catalog);

const dependency = structUtils.makeDescriptor(
structUtils.makeIdent(null, `react`),
`catalog:`,
);
mockResolver.supportsDescriptor.mockReturnValue(false);

const resolved = resolveDescriptorFromCatalog(project, dependency, mockResolver, resolveOptions);

expect(mockResolver.bindDescriptor).toHaveBeenCalledTimes(0);
expect(resolved.range).toBe(`custom:^18.0.0`);
expect(structUtils.stringifyIdent(resolved)).toBe(`react`);
});

it(`should normalize the resolved descriptor`, () => {
const catalog = new Map([
[`typescript`, `^5.0.0`],
Expand Down