@@ -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,10 @@ 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+ if ( packageIdentifier . rawSpec === '*' ) {
235+ packageIdentifier . fetchSpec = options . next ? 'next' : 'latest' ;
236+ packageIdentifier . type = 'tag' ;
237237 }
238238
239239 packages . push ( packageIdentifier as PackageIdentifier ) ;
@@ -665,36 +665,45 @@ export default class UpdateCommandModule extends CommandModule<UpdateCommandArgs
665665 // Try to find a package version based on the user requested package specifier
666666 // registry specifier types are either version, range, or tag
667667 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.
668+ switch ( requestIdentifier . type ) {
669+ case 'tag' :
670+ manifest = metadata . tags [ requestIdentifier . fetchSpec ] ;
671+ // If not found and next option was used and user did not provide a specifier, try latest.
672+ // Package may not have a next tag.
673+ if (
674+ ! manifest &&
675+ requestIdentifier . fetchSpec === 'next' &&
676+ requestIdentifier . rawSpec === '*'
677+ ) {
678+ manifest = metadata . tags [ 'latest' ] ;
679+ }
680+ break ;
681+ case 'version' :
682+ manifest = metadata . versions [ requestIdentifier . fetchSpec ] ;
683+ break ;
684+ case 'range' :
685+ for ( const potentialManifest of Object . values ( metadata . versions ) ) {
686+ // Ignore deprecated package versions
687+ if ( potentialManifest . deprecated ) {
688+ continue ;
689+ }
690+ // Only consider versions that are within the range
680691 if (
681- requestIdentifier . type === 'tag' &&
682- requestIdentifier . fetchSpec === 'next' &&
683- ! requestIdentifier . rawSpec
692+ ! semver . satisfies ( potentialManifest . version , requestIdentifier . fetchSpec , {
693+ loose : true ,
694+ } )
684695 ) {
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- }
696+ continue ;
697+ }
698+ // Update the used manifest if current potential is newer than existing or there is not one yet
699+ if (
700+ ! manifest ||
701+ semver . gt ( potentialManifest . version , manifest . version , { loose : true } )
702+ ) {
703+ manifest = potentialManifest ;
693704 }
694- } else if ( e . code !== 'ENOVERSIONS' ) {
695- throw e ;
696705 }
697- }
706+ break ;
698707 }
699708
700709 if ( ! manifest ) {
0 commit comments