@@ -43,15 +43,14 @@ final class DownloadCountService {
4343 do {
4444 let releases = try await fetchReleases ( )
4545 let pluginReleases = releases. filter { $0. tagName. hasPrefix ( " plugin- " ) }
46- let urlToPluginId = buildURLMap ( from: manifest)
46+ let tagPrefixToPluginId = buildTagPrefixMap ( from: manifest)
4747
4848 var totals : [ String : Int ] = [ : ]
4949 for release in pluginReleases {
50- for asset in release. assets {
51- if let pluginId = urlToPluginId [ asset. browserDownloadUrl] {
52- totals [ pluginId, default: 0 ] += asset. downloadCount
53- }
54- }
50+ let tagPrefix = extractTagPrefix ( from: release. tagName)
51+ guard let pluginId = tagPrefixToPluginId [ tagPrefix] else { continue }
52+ let releaseTotal = release. assets. reduce ( 0 ) { $0 + $1. downloadCount }
53+ totals [ pluginId, default: 0 ] += releaseTotal
5554 }
5655
5756 counts = totals
@@ -80,22 +79,32 @@ final class DownloadCountService {
8079 return try decoder. decode ( [ GitHubRelease ] . self, from: data)
8180 }
8281
83- // MARK: - URL Mapping
82+ // MARK: - Tag Prefix Mapping
8483
85- private func buildURLMap ( from manifest: RegistryManifest ) -> [ String : String ] {
84+ private func buildTagPrefixMap ( from manifest: RegistryManifest ) -> [ String : String ] {
8685 var map : [ String : String ] = [ : ]
8786 for plugin in manifest. plugins {
88- if let binaries = plugin. binaries {
89- for binary in binaries {
90- map [ binary. downloadURL] = plugin. id
91- }
92- }
93- if let url = plugin. downloadURL {
94- map [ url] = plugin. id
95- }
87+ let url = plugin. binaries? . first? . downloadURL ?? plugin. downloadURL
88+ guard let url else { continue }
89+ guard let tagComponent = extractTagComponent ( from: url) else { continue }
90+ let prefix = extractTagPrefix ( from: tagComponent)
91+ map [ prefix] = plugin. id
9692 }
9793 return map
9894 }
95+
96+ private func extractTagComponent( from downloadURL: String ) -> String ? {
97+ guard let url = URL ( string: downloadURL) else { return nil }
98+ let components = url. pathComponents
99+ guard let downloadIndex = components. firstIndex ( of: " download " ) ,
100+ downloadIndex + 1 < components. count else { return nil }
101+ return components [ downloadIndex + 1 ]
102+ }
103+
104+ private func extractTagPrefix( from tag: String ) -> String {
105+ guard let range = tag. range ( of: #"-v\d"# , options: . regularExpression) else { return tag }
106+ return String ( tag [ tag. startIndex..< range. lowerBound] )
107+ }
99108}
100109
101110// MARK: - GitHub API Models
0 commit comments