|
1 |
| -import {Cache, DescriptorHash, Descriptor, Ident, Locator, Manifest, Project, ThrowReport, Workspace, FetchOptions, ResolveOptions, Configuration} from '@yarnpkg/core'; |
2 |
| -import {formatUtils, structUtils, semverUtils} from '@yarnpkg/core'; |
3 |
| -import {PortablePath, ppath, xfs} from '@yarnpkg/fslib'; |
4 |
| -import semver from 'semver'; |
| 1 | +import {Cache, DescriptorHash, Descriptor, Ident, Locator, Manifest, Project, ThrowReport, Workspace, FetchOptions, ResolveOptions, Configuration, TAG_REGEXP} from '@yarnpkg/core'; |
| 2 | +import {formatUtils, structUtils, semverUtils} from '@yarnpkg/core'; |
| 3 | +import {PortablePath, ppath, xfs} from '@yarnpkg/fslib'; |
| 4 | +import semver from 'semver'; |
5 | 5 |
|
6 | 6 | const WORKSPACE_PROTOCOL = `workspace:`;
|
7 | 7 |
|
@@ -204,17 +204,56 @@ export async function extractDescriptorFromPath(path: PortablePath, {cwd, worksp
|
204 | 204 | });
|
205 | 205 | }
|
206 | 206 |
|
| 207 | +type InferenceParameters = { |
| 208 | + type: `fixed`; |
| 209 | + range: string; |
| 210 | +} | { |
| 211 | + type: `resolve`; |
| 212 | + range: string; |
| 213 | +}; |
| 214 | + |
| 215 | + |
| 216 | +function extractInferenceParametersFromRequest(request: Descriptor): InferenceParameters { |
| 217 | + if (request.range === `unknown`) |
| 218 | + return {type: `resolve`, range: `latest`}; |
| 219 | + |
| 220 | + if (semverUtils.validRange(request.range)) |
| 221 | + return {type: `fixed`, range: request.range}; |
| 222 | + |
| 223 | + if (TAG_REGEXP.test(request.range)) |
| 224 | + return {type: `resolve`, range: request.range}; |
| 225 | + |
| 226 | + const registryProtocol = request.range.match(/^(?:jsr:|npm:)(.*)/); |
| 227 | + if (!registryProtocol) |
| 228 | + return {type: `fixed`, range: request.range}; |
| 229 | + |
| 230 | + let [, range] = registryProtocol; |
| 231 | + |
| 232 | + // Try to handle the case of "foo@jsr:foo@latest", because otherwise there |
| 233 | + // would be no way to cleanly add a package from a 3rd-party registry using |
| 234 | + // a tag (since foo@jsr:latest would refer to "the package named 'latest'"). |
| 235 | + const selfRegistryPrefix = `${structUtils.stringifyIdent(request)}@`; |
| 236 | + if (range.startsWith(selfRegistryPrefix)) |
| 237 | + range = range.slice(selfRegistryPrefix.length); |
| 238 | + |
| 239 | + if (semverUtils.validRange(range)) |
| 240 | + return {type: `fixed`, range: request.range}; |
| 241 | + |
| 242 | + if (TAG_REGEXP.test(range)) |
| 243 | + return {type: `resolve`, range: request.range}; |
| 244 | + |
| 245 | + return {type: `fixed`, range: request.range}; |
| 246 | +} |
| 247 | + |
207 | 248 | export async function getSuggestedDescriptors(request: Descriptor, {project, workspace, cache, target, fixed, modifier, strategies, maxResults = Infinity}: {project: Project, workspace: Workspace, cache: Cache, target: Target, fixed: boolean, modifier: Modifier, strategies: Array<Strategy>, maxResults?: number}): Promise<Results> {
|
208 | 249 | if (!(maxResults >= 0))
|
209 | 250 | throw new Error(`Invalid maxResults (${maxResults})`);
|
210 | 251 |
|
211 |
| - const [requestRange, requestTag] = request.range !== `unknown` |
212 |
| - ? fixed || semverUtils.validRange(request.range) || !request.range.match(/^[a-z0-9._-]+$/i) |
213 |
| - ? [request.range, `latest`] |
214 |
| - : [`unknown`, request.range] |
215 |
| - : [`unknown`, `latest`]; |
| 252 | + const inference = !fixed || request.range === `unknown` |
| 253 | + ? extractInferenceParametersFromRequest(request) |
| 254 | + : {type: `fixed`, range: request.range}; |
216 | 255 |
|
217 |
| - if (requestRange !== `unknown`) { |
| 256 | + if (inference.type === `fixed`) { |
218 | 257 | return {
|
219 | 258 | suggestions: [{
|
220 | 259 | descriptor: request,
|
@@ -332,7 +371,7 @@ export async function getSuggestedDescriptors(request: Descriptor, {project, wor
|
332 | 371 | reason: formatUtils.pretty(project.configuration, `(unavailable because enableNetwork is toggled off)`, `grey`),
|
333 | 372 | });
|
334 | 373 | } else {
|
335 |
| - const latest = await fetchDescriptorFrom(request, requestTag, {project, cache, workspace, modifier}); |
| 374 | + const latest = await fetchDescriptorFrom(request, inference.range, {project, cache, workspace, modifier}); |
336 | 375 | if (latest) {
|
337 | 376 | suggested.push({
|
338 | 377 | descriptor: latest,
|
|
0 commit comments