@@ -137,6 +137,45 @@ export function usePackageDownloads(
137137 )
138138}
139139
140+ type NpmDownloadsRangeResponse = {
141+ start : string
142+ end : string
143+ package : string
144+ downloads : Array < { day : string , downloads : number } >
145+ }
146+
147+ async function fetchNpmDownloadsRange (
148+ packageName : string ,
149+ start : string ,
150+ end : string ,
151+ ) : Promise < NpmDownloadsRangeResponse > {
152+ const encodedName = encodePackageName ( packageName )
153+ return await $fetch < NpmDownloadsRangeResponse > ( `${ NPM_API } /downloads/range/${ start } :${ end } /${ encodedName } ` )
154+ }
155+
156+ export function usePackageWeeklyDownloadEvolution (
157+ name : MaybeRefOrGetter < string > ,
158+ options : MaybeRefOrGetter < {
159+ weeks ?: number
160+ endDate ?: string
161+ } > = { } ,
162+ ) {
163+ return useLazyAsyncData (
164+ ( ) => `downloads-weekly-evolution:${ toValue ( name ) } :${ JSON . stringify ( toValue ( options ) ) } ` ,
165+ async ( ) => {
166+ const packageName = toValue ( name )
167+ const { weeks = 12 , endDate } = toValue ( options ) ?? { }
168+ const end = endDate ? new Date ( `${ endDate } T00:00:00.000Z` ) : new Date ( )
169+ const start = addDays ( end , - ( weeks * 7 ) + 1 )
170+ const startIso = toIsoDateString ( start )
171+ const endIso = toIsoDateString ( end )
172+ const range = await fetchNpmDownloadsRange ( packageName , startIso , endIso )
173+ const sortedDaily = [ ...range . downloads ] . sort ( ( a , b ) => a . day . localeCompare ( b . day ) )
174+ return buildWeeklyEvolutionFromDaily ( sortedDaily )
175+ } ,
176+ )
177+ }
178+
140179const emptySearchResponse = { objects : [ ] , total : 0 , time : new Date ( ) . toISOString ( ) } satisfies NpmSearchResponse
141180
142181export function useNpmSearch (
0 commit comments