yarn-plugin: implement BackstageResolver#getSatisfying

It turns out this method is called for
`backstage:` descriptors during `yarn dedupe`, so
we need to implement it.

Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com>
This commit is contained in:
MT Lewis
2024-07-27 14:28:55 +01:00
parent 2bae52597d
commit 9e2918640a
2 changed files with 106 additions and 8 deletions
@@ -178,4 +178,87 @@ describe('BackstageResolver', () => {
).rejects.toThrow(/invalid backstage version/i);
});
});
describe('getSatisfying', () => {
it('filters out locators for other packages', async () => {
await expect(
backstageResolver.getSatisfying(
structUtils.makeDescriptor(
structUtils.makeIdent('backstage', 'core'),
'backstage:1.23.45',
),
{},
[
structUtils.makeLocator(
structUtils.makeIdent('backstage', 'foo'),
'npm:1.2.3',
),
structUtils.makeLocator(
structUtils.makeIdent('backstage', 'core'),
'npm:6.7.8',
),
structUtils.makeLocator(
structUtils.makeIdent('backstage', 'bar'),
'npm:1.2.3',
),
],
),
).resolves.toEqual({
locators: [
structUtils.makeLocator(
structUtils.makeIdent('backstage', 'core'),
'npm:6.7.8',
),
],
sorted: true,
});
});
it('filters out locators for other package versions', async () => {
await expect(
backstageResolver.getSatisfying(
structUtils.makeDescriptor(
structUtils.makeIdent('backstage', 'core'),
'backstage:1.23.45',
),
{},
[
structUtils.makeLocator(
structUtils.makeIdent('backstage', 'core'),
'npm:5.6.7',
),
structUtils.makeLocator(
structUtils.makeIdent('backstage', 'core'),
'npm:6.7.8',
),
structUtils.makeLocator(
structUtils.makeIdent('backstage', 'bar'),
'npm:7.8.9',
),
],
),
).resolves.toEqual({
locators: [
structUtils.makeLocator(
structUtils.makeIdent('backstage', 'core'),
'npm:6.7.8',
),
],
sorted: true,
});
});
it('throws for non `backstage:` descriptors', async () => {
await expect(
backstageResolver.getSatisfying(
structUtils.makeDescriptor(
structUtils.makeIdent('backstage', 'core'),
'npm:1.2.3',
),
{},
[],
),
).rejects.toThrow(/unexpected npm: range/i);
});
});
});
@@ -92,6 +92,29 @@ export class BackstageResolver implements Resolver {
];
}
/**
* Given a descriptor and a list of possible locators, return a filtered list
* containing only locators that satisfy the descriptor. Since each Backstage
* release version corresponds to a single version for each package, we just
* need to filter that array for locators with that exact version.
*/
async getSatisfying(
descriptor: Descriptor,
_dependencies: Record<string, Package>,
locators: Array<Locator>,
): Promise<{ locators: Locator[]; sorted: boolean }> {
const packageVersion = await getPackageVersion(descriptor);
return {
locators: locators.filter(
locator =>
structUtils.areIdentsEqual(descriptor, locator) &&
locator.reference === `npm:${packageVersion}`,
),
sorted: true,
};
}
/**
* This plugin does not need to support any locators itself, since the
* `getCandidates` method will always convert `backstage:` versions into
@@ -106,14 +129,6 @@ export class BackstageResolver implements Resolver {
*/
getResolutionDependencies = () => ({});
/**
* Candidate versions produced by this resolver always use the `npm:`
* protocol, so this function will never be called.
*/
async getSatisfying(): Promise<{ locators: Locator[]; sorted: boolean }> {
throw new Error('Unreachable');
}
/**
* Once transformed into locators (through getCandidates), the versions are
* resolved by the NpmSemverResolver