@@ -44,8 +44,14 @@ export interface PackageComparisonData {
4444 * but a maintainer was removed last week, this would show the '3 years ago' time.
4545 */
4646 lastUpdated ?: string
47+ /** Creation date of the package (ISO 8601 date-time string) */
48+ createdAt ?: string
4749 engines ?: { node ?: string ; npm ?: string }
48- deprecated ?: string
50+ deprecated ?: string ,
51+ github ?: {
52+ stars ?: number
53+ issues ?: number
54+ }
4955 }
5056 /** Whether this is a binary-only package (CLI without library entry points) */
5157 isBinaryOnly ?: boolean
@@ -115,12 +121,11 @@ export function usePackageComparison(packageNames: MaybeRefOrGetter<string[]>) {
115121 try {
116122 // Fetch basic package info first (required)
117123 const { data : pkgData } = await $npmRegistry < Packument > ( `/${ encodePackageName ( name ) } ` )
118-
119124 const latestVersion = pkgData [ 'dist-tags' ] ?. latest
120125 if ( ! latestVersion ) return null
121126
122127 // Fetch fast additional data in parallel (optional - failures are ok)
123- const [ downloads , analysis , vulns , likes ] = await Promise . all ( [
128+ const [ downloads , analysis , vulns , likes , ghStars , ghIssues ] = await Promise . all ( [
124129 $fetch < { downloads : number } > (
125130 `https://api.npmjs.org/downloads/point/last-week/${ encodePackageName ( name ) } ` ,
126131 ) . catch ( ( ) => null ) ,
@@ -133,6 +138,8 @@ export function usePackageComparison(packageNames: MaybeRefOrGetter<string[]>) {
133138 $fetch < PackageLikes > ( `/api/social/likes/${ encodePackageName ( name ) } ` ) . catch (
134139 ( ) => null ,
135140 ) ,
141+ $fetch < { repo : { stars : number } } > ( `https://ungh.cc/repos/${ parseRepositoryInfo ( pkgData . repository ) ?. owner } /${ parseRepositoryInfo ( pkgData . repository ) ?. repo } ` ) . then ( res => res ?. repo . stars || 0 ) . catch ( ( ) => null ) ,
142+ $fetch < { issues : number } > ( `/api/github/issues/${ parseRepositoryInfo ( pkgData . repository ) ?. owner } /${ parseRepositoryInfo ( pkgData . repository ) ?. repo } ` ) . then ( res => res ?. issues || 0 ) . catch ( ( ) => null ) ,
136143 ] )
137144 const versionData = pkgData . versions [ latestVersion ]
138145 const packageSize = versionData ?. dist ?. unpackedSize
@@ -179,8 +186,13 @@ export function usePackageComparison(packageNames: MaybeRefOrGetter<string[]>) {
179186 // Use version-specific publish time, NOT time.modified (which can be
180187 // updated by metadata changes like maintainer additions)
181188 lastUpdated : pkgData . time ?. [ latestVersion ] ,
189+ createdAt : pkgData . time ?. created ,
182190 engines : analysis ?. engines ,
183191 deprecated : versionData ?. deprecated ,
192+ github : {
193+ stars : ghStars ?? undefined ,
194+ issues : ghIssues ?? undefined ,
195+ } ,
184196 } ,
185197 isBinaryOnly : isBinary ,
186198 totalLikes : likes ?. totalLikes ,
@@ -252,6 +264,7 @@ export function usePackageComparison(packageNames: MaybeRefOrGetter<string[]>) {
252264
253265 return packagesData . value . map ( pkg => {
254266 if ( ! pkg ) return null
267+ console . log ( pkg . package . name , { pkg} )
255268 return computeFacetValue (
256269 facet ,
257270 pkg ,
@@ -538,6 +551,43 @@ function computeFacetValue(
538551 status : totalDepCount > 50 ? 'warning' : 'neutral' ,
539552 }
540553 }
554+ case 'githubStars' : {
555+ const stars = data . metadata ?. github ?. stars
556+ if ( stars == null ) return null
557+ return {
558+ raw : stars ,
559+ display : formatCompactNumber ( stars ) ,
560+ status : stars > 1000 ? 'good' : 'neutral' ,
561+ }
562+ }
563+ case 'githubIssues' : {
564+ const issues = data . metadata ?. github ?. issues
565+ if ( issues == null ) return null
566+ const stars = data . metadata ?. github ?. stars
567+ const ratio = stars && issues > 0 ? issues / stars : null
568+ return {
569+ raw : issues ,
570+ display : formatCompactNumber ( issues ) ,
571+ // High issues-to-stars ratio suggests the project is struggling relative to its popularity
572+ status : ratio == null || ratio < 0.1 ? 'good' : ratio < 0.5 ? 'neutral' : 'warning' ,
573+ }
574+ }
575+ case 'createdAt' : {
576+ const createdAt = data . metadata ?. createdAt
577+ const resolved = createdAt ? resolveNoDependencyDisplay ( createdAt , t ) : null
578+ if ( resolved ) return { raw : 0 , ...resolved }
579+ if ( ! createdAt ) return null
580+ const date = new Date ( createdAt )
581+ const oneMonthAgo = new Date ( )
582+ oneMonthAgo . setMonth ( oneMonthAgo . getMonth ( ) - 1 )
583+ return {
584+ raw : date . getTime ( ) ,
585+ display : createdAt ,
586+ // Package is rated "good" if it was created more than a month ago (not brand new)
587+ status : date < oneMonthAgo ? 'good' : 'neutral' ,
588+ type : 'date' ,
589+ }
590+ }
541591 default : {
542592 return null
543593 }
0 commit comments