1- #! /usr/bin/env node
1+ #!/usr/bin/env node
22import path from "path" ;
33import fs from "fs" ;
44import https from "https" ;
@@ -49,15 +49,28 @@ function getJSON<T>(url: string): Promise<T> {
4949 } ) ;
5050}
5151
52+ // A subset of the response returned by npm's registry
53+ type RegistryResponse = {
54+ "dist-tags" : Record < string , string > ;
55+ time : {
56+ created : string ;
57+ modified : string ;
58+ [ version : string ] : string ;
59+ } ;
60+ } ;
61+
5262type PackageInfo = {
5363 name : string ;
54- modifiedDate ?: Date ;
64+ mostRecentReleaseDate ?: Date ;
5565} ;
5666
57- function isDitched ( { modifiedDate } : PackageInfo , ditchDays : number ) : boolean {
58- if ( ! modifiedDate ) return false ;
67+ function isDitched (
68+ { mostRecentReleaseDate } : PackageInfo ,
69+ ditchDays : number
70+ ) : boolean {
71+ if ( ! mostRecentReleaseDate ) return false ;
5972 const ageDays =
60- differenceInMilliseconds ( new Date ( ) , modifiedDate ) / MS_IN_A_DAY ;
73+ differenceInMilliseconds ( new Date ( ) , mostRecentReleaseDate ) / MS_IN_A_DAY ;
6174 return ageDays > ditchDays ;
6275}
6376
@@ -77,27 +90,30 @@ function printInfoTable(
7790 const table = new CliTable ( {
7891 head : [
7992 chalk . gray ( "Package" ) ,
80- chalk . gray ( "Last Modified " ) ,
93+ chalk . gray ( "Latest Release " ) ,
8194 chalk . gray ( "Ditched?" ) ,
8295 ] ,
8396 colWidths : [ 30 , 40 , 15 ] ,
8497 } ) ;
8598
8699 packagesToShow
87100 . sort ( ( a , b ) => {
88- if ( ! a . modifiedDate ) return - 1 ;
89- if ( ! b . modifiedDate ) return 1 ;
90- return differenceInMilliseconds ( b . modifiedDate , a . modifiedDate ) ;
101+ if ( ! a . mostRecentReleaseDate ) return - 1 ;
102+ if ( ! b . mostRecentReleaseDate ) return 1 ;
103+ return differenceInMilliseconds (
104+ b . mostRecentReleaseDate ,
105+ a . mostRecentReleaseDate
106+ ) ;
91107 } )
92108 . forEach ( ( packageInfo ) => {
93- const { name, modifiedDate } = packageInfo ;
109+ const { name, mostRecentReleaseDate } = packageInfo ;
94110
95- const formattedTime = modifiedDate
96- ? formatTimeSince ( modifiedDate )
111+ const formattedTime = mostRecentReleaseDate
112+ ? formatTimeSince ( mostRecentReleaseDate )
97113 : "No package info found." ;
98114
99115 let ditchedInfo = chalk . red ( "?" ) ;
100- if ( modifiedDate ) {
116+ if ( mostRecentReleaseDate ) {
101117 ditchedInfo = isDitched ( packageInfo , ditchDays )
102118 ? chalk . red ( "Yes" )
103119 : chalk . green ( "No" ) ;
@@ -112,12 +128,18 @@ function printInfoTable(
112128async function getInfoForPackage ( packageName : string ) : Promise < PackageInfo > {
113129 try {
114130 const regUrl = REGISTRY_URL + "/" + packageName ;
115- const response = await getJSON < { time : { modified : string } } > ( regUrl ) ;
116- const modifiedDate = new Date ( response . time . modified ) ;
131+ const response = await getJSON < RegistryResponse > ( regUrl ) ;
132+
133+ const mostRecentReleaseDate = new Date (
134+ Object . entries ( response . time )
135+ . filter ( ( [ key ] ) => key !== "created" && key !== "modified" )
136+ . map ( ( [ , value ] ) => value )
137+ . reduce ( ( acc , el ) => ( el > acc ? el : acc ) )
138+ ) ;
117139
118140 return {
119141 name : packageName ,
120- modifiedDate ,
142+ mostRecentReleaseDate ,
121143 } ;
122144 } catch ( error ) {
123145 return {
0 commit comments