@@ -19,7 +19,6 @@ import { createRequire } from 'node:module';
1919import * as path from 'node:path' ;
2020import { join , resolve } from 'node:path' ;
2121import npa from 'npm-package-arg' ;
22- import pickManifest from 'npm-pick-manifest' ;
2322import * as semver from 'semver' ;
2423import { Argv } from 'yargs' ;
2524import { PackageManager } from '../../../lib/config/workspace-schema' ;
@@ -231,9 +230,11 @@ export default class UpdateCommandModule extends CommandModule<UpdateCommandArgs
231230 logger . warn ( 'Package specifier has no effect when using "migrate-only" option.' ) ;
232231 }
233232
234- // If next option is used and no specifier supplied, use next tag
235- if ( options . next && packageIdentifier . rawSpec === '*' ) {
236- packageIdentifier . fetchSpec = 'next' ;
233+ // Wildcard uses the next tag if next option is used otherwise use latest tag.
234+ // Wildcard is present if no selector is provided on the command line.
235+ if ( packageIdentifier . rawSpec === '*' ) {
236+ packageIdentifier . fetchSpec = options . next ? 'next' : 'latest' ;
237+ packageIdentifier . type = 'tag' ;
237238 }
238239
239240 packages . push ( packageIdentifier as PackageIdentifier ) ;
@@ -665,36 +666,45 @@ export default class UpdateCommandModule extends CommandModule<UpdateCommandArgs
665666 // Try to find a package version based on the user requested package specifier
666667 // registry specifier types are either version, range, or tag
667668 let manifest : PackageManifest | undefined ;
668- if (
669- requestIdentifier . type === 'version' ||
670- requestIdentifier . type === 'range' ||
671- requestIdentifier . type === 'tag'
672- ) {
673- try {
674- manifest = pickManifest ( metadata , requestIdentifier . fetchSpec ) ;
675- } catch ( e ) {
676- assertIsError ( e ) ;
677- if ( e . code === 'ETARGET' ) {
678- // If not found and next was used and user did not provide a specifier, try latest.
679- // Package may not have a next tag.
669+ switch ( requestIdentifier . type ) {
670+ case 'tag' :
671+ manifest = metadata . tags [ requestIdentifier . fetchSpec ] ;
672+ // If not found and next option was used and user did not provide a specifier, try latest.
673+ // Package may not have a next tag.
674+ if (
675+ ! manifest &&
676+ requestIdentifier . fetchSpec === 'next' &&
677+ requestIdentifier . rawSpec === '*'
678+ ) {
679+ manifest = metadata . tags [ 'latest' ] ;
680+ }
681+ break ;
682+ case 'version' :
683+ manifest = metadata . versions [ requestIdentifier . fetchSpec ] ;
684+ break ;
685+ case 'range' :
686+ for ( const potentialManifest of Object . values ( metadata . versions ) ) {
687+ // Ignore deprecated package versions
688+ if ( potentialManifest . deprecated ) {
689+ continue ;
690+ }
691+ // Only consider versions that are within the range
680692 if (
681- requestIdentifier . type === 'tag' &&
682- requestIdentifier . fetchSpec === 'next' &&
683- ! requestIdentifier . rawSpec
693+ ! semver . satisfies ( potentialManifest . version , requestIdentifier . fetchSpec , {
694+ loose : true ,
695+ } )
684696 ) {
685- try {
686- manifest = pickManifest ( metadata , 'latest' ) ;
687- } catch ( e ) {
688- assertIsError ( e ) ;
689- if ( e . code !== 'ETARGET' && e . code !== 'ENOVERSIONS' ) {
690- throw e ;
691- }
692- }
697+ continue ;
698+ }
699+ // Update the used manifest if current potential is newer than existing or there is not one yet
700+ if (
701+ ! manifest ||
702+ semver . gt ( potentialManifest . version , manifest . version , { loose : true } )
703+ ) {
704+ manifest = potentialManifest ;
693705 }
694- } else if ( e . code !== 'ENOVERSIONS' ) {
695- throw e ;
696706 }
697- }
707+ break ;
698708 }
699709
700710 if ( ! manifest ) {
0 commit comments