@@ -135,6 +135,11 @@ public override PackageRegistration FindPackageRegistrationById(string packageId
135135 . SingleOrDefault ( pr => pr . Id == packageId ) ;
136136 }
137137
138+ public virtual IReadOnlyCollection < Package > FindPackagesById ( string id , bool withDeprecations = false )
139+ {
140+ return GetPackagesByIdQueryable ( id , withDeprecations ) . ToList ( ) ;
141+ }
142+
138143 public virtual Package FindPackageByIdAndVersion (
139144 string id ,
140145 string version ,
@@ -170,62 +175,68 @@ public virtual Package FindPackageByIdAndVersion(
170175
171176 var packageVersions = packagesQuery . ToList ( ) ;
172177
173- // Fallback behavior: collect the latest version.
174- // Check SemVer-level and allow-prerelease constraints.
175- if ( semVerLevelKey == SemVerLevelKey . SemVer2 )
176- {
177- package = packageVersions . FirstOrDefault ( p => p . IsLatestStableSemVer2 ) ;
178-
179- if ( package == null && allowPrerelease )
180- {
181- package = packageVersions . FirstOrDefault ( p => p . IsLatestSemVer2 ) ;
182- }
183- }
184-
185- // Fallback behavior: collect the latest version.
186- // If SemVer-level is not defined,
187- // or SemVer-level = 2.0.0 and no package was marked as SemVer2-latest,
188- // then check for packages marked as non-SemVer2 latest.
189- if ( semVerLevelKey == SemVerLevelKey . Unknown
190- || ( semVerLevelKey == SemVerLevelKey . SemVer2 && package == null ) )
191- {
192- package = packageVersions . FirstOrDefault ( p => p . IsLatestStable ) ;
193-
194- if ( package == null && allowPrerelease )
195- {
196- package = packageVersions . FirstOrDefault ( p => p . IsLatest ) ;
197- }
198- }
199-
200- // If we couldn't find a package marked as latest, then
201- // return the most recent one (prerelease ones were already filtered out if appropriate...)
202- if ( package == null )
203- {
204- package = packageVersions . OrderByDescending ( p => p . Version ) . FirstOrDefault ( ) ;
205- }
178+ package = FilterLatestPackageHelper ( packageVersions , semVerLevelKey , allowPrerelease ) ;
206179 }
207180
208181 return package ;
209182 }
210183
211- public virtual Package FindAbsoluteLatestPackageById ( string id , int ? semVerLevelKey )
184+ public virtual Package FilterLatestPackage (
185+ IReadOnlyCollection < Package > packages ,
186+ int ? semVerLevelKey = SemVerLevelKey . SemVer2 ,
187+ bool allowPrerelease = true )
212188 {
213- var packageVersions = GetPackagesByIdQueryable ( id ) ;
189+ return FilterLatestPackageHelper (
190+ // Filter out prereleases in the list if prereleases are not allowed.
191+ packages ? . Where ( p => allowPrerelease || ! p . IsPrerelease ) . ToList ( ) ,
192+ semVerLevelKey ,
193+ allowPrerelease ) ;
194+ }
214195
215- Package package ;
196+ private static Package FilterLatestPackageHelper (
197+ IReadOnlyCollection < Package > packages ,
198+ int ? semVerLevelKey ,
199+ bool allowPrerelease )
200+ {
201+ if ( packages == null )
202+ {
203+ throw new ArgumentNullException ( nameof ( packages ) ) ;
204+ }
205+
206+ Package package = null ;
207+
208+ // Fallback behavior: collect the latest version.
209+ // Check SemVer-level and allow-prerelease constraints.
216210 if ( semVerLevelKey == SemVerLevelKey . SemVer2 )
217211 {
218- package = packageVersions . FirstOrDefault ( p => p . IsLatestSemVer2 ) ;
212+ package = packages . FirstOrDefault ( p => p . IsLatestStableSemVer2 ) ;
213+
214+ if ( package == null && allowPrerelease )
215+ {
216+ package = packages . FirstOrDefault ( p => p . IsLatestSemVer2 ) ;
217+ }
219218 }
220- else
219+
220+ // Fallback behavior: collect the latest version.
221+ // If SemVer-level is not defined,
222+ // or SemVer-level = 2.0.0 and no package was marked as SemVer2-latest,
223+ // then check for packages marked as non-SemVer2 latest.
224+ if ( semVerLevelKey == SemVerLevelKey . Unknown
225+ || ( semVerLevelKey == SemVerLevelKey . SemVer2 && package == null ) )
221226 {
222- package = packageVersions . FirstOrDefault ( p => p . IsLatest ) ;
227+ package = packages . FirstOrDefault ( p => p . IsLatestStable ) ;
228+
229+ if ( package == null && allowPrerelease )
230+ {
231+ package = packages . FirstOrDefault ( p => p . IsLatest ) ;
232+ }
223233 }
224234
225- // If we couldn't find a package marked as latest, then return the most recent one
235+ // If we couldn't find a package marked as latest, then return the most recent one.
236+ // Prereleases were already filtered out if appropriate.
226237 if ( package == null )
227238 {
228- package = packageVersions . OrderByDescending ( p => p . Version ) . FirstOrDefault ( ) ;
239+ package = packages . OrderByDescending ( p => p . Version ) . FirstOrDefault ( ) ;
229240 }
230241
231242 return package ;
@@ -277,7 +288,7 @@ private IEnumerable<Package> GetPackagesForOwners(IEnumerable<int> ownerKeys, bo
277288 . ThenByDescending ( p => p . Key )
278289 . FirstOrDefault ( ) ) ;
279290 }
280-
291+
281292 return packages
282293 . Include ( p => p . PackageRegistration )
283294 . Include ( p => p . PackageRegistration . Owners )
@@ -360,7 +371,7 @@ public async Task RemovePackageOwnerAsync(PackageRegistration package, User user
360371 await _packageRepository . CommitChangesAsync ( ) ;
361372 }
362373 }
363-
374+
364375 public bool WillPackageBeOrphanedIfOwnerRemoved ( PackageRegistration package , User ownerToRemove )
365376 {
366377 return WillPackageBeOrphanedIfOwnerRemovedHelper ( package . Owners , ownerToRemove ) ;
0 commit comments