@@ -70,6 +70,10 @@ const FULL_DETAILS_TTL = 60 * 60 * 2; // 2 hours
70
70
* The TTL of the cached descriptions, in seconds.
71
71
*/
72
72
const DESCRIPTIONS_TTL = 60 * 60 * 24 * 10 ; // 10 days
73
+ /**
74
+ * The TTL for non-deprecated packages, in seconds
75
+ */
76
+ const DEPRECATIONS_TTL = 60 * 60 * 24 * 2 ; // 2 days
73
77
74
78
/**
75
79
* A fetch layer to reach the GitHub API
@@ -115,6 +119,21 @@ export class GitHubCache {
115
119
return `repo:${ owner } /${ repo } :${ type } ${ strArgs } ` ;
116
120
}
117
121
122
+ /**
123
+ * Generates a Redis key from the passed info.
124
+ *
125
+ * @param packageName the package name
126
+ * @param args the optional additional values to append
127
+ * at the end of the key; every element will be interpolated
128
+ * in a string
129
+ * @returns the pure computed key
130
+ * @private
131
+ */
132
+ #getPackageKey( packageName : string , ...args : unknown [ ] ) {
133
+ const strArgs = args . map ( a => `:${ a } ` ) ;
134
+ return `package:${ packageName } ${ strArgs } ` ;
135
+ }
136
+
118
137
/**
119
138
* An abstraction over general processing that:
120
139
* 1. tries getting stuff from Redis cache
@@ -138,7 +157,7 @@ export class GitHubCache {
138
157
cacheKey : string ,
139
158
promise : ( ) => Promise < PromiseType > ,
140
159
transformer : ( from : Awaited < PromiseType > ) => RType | Promise < RType > ,
141
- ttl : number | undefined = undefined
160
+ ttl : number | ( ( value : RType ) => number | undefined ) | undefined = undefined
142
161
) : Promise < RType > => {
143
162
const cachedValue = await this . #redis. json . get < RType > ( cacheKey ) ;
144
163
if ( cachedValue ) {
@@ -152,7 +171,14 @@ export class GitHubCache {
152
171
153
172
await this . #redis. json . set ( cacheKey , "$" , newValue ) ;
154
173
if ( ttl !== undefined ) {
155
- await this . #redis. expire ( cacheKey , ttl ) ;
174
+ if ( typeof ttl === "function" ) {
175
+ const ttlResult = ttl ( newValue ) ;
176
+ if ( ttlResult !== undefined ) {
177
+ await this . #redis. expire ( cacheKey , ttlResult ) ;
178
+ }
179
+ } else {
180
+ await this . #redis. expire ( cacheKey , ttl ) ;
181
+ }
156
182
}
157
183
158
184
return newValue ;
@@ -537,7 +563,6 @@ export class GitHubCache {
537
563
* @param repo the GitHub repository name to fetch the
538
564
* descriptions in
539
565
* @returns a map of paths to descriptions.
540
- * @private
541
566
*/
542
567
async getDescriptions ( owner : string , repo : string ) {
543
568
return await this . #processCached< { [ key : string ] : string } > ( ) (
@@ -586,6 +611,37 @@ export class GitHubCache {
586
611
DESCRIPTIONS_TTL
587
612
) ;
588
613
}
614
+
615
+ /**
616
+ * Get the deprecation state of a package from its name.
617
+ *
618
+ * @param packageName the name of the package to search
619
+ * @returns the deprecation status message if any, `false` otherwise
620
+ */
621
+ async getPackageDeprecation ( packageName : string ) {
622
+ return await this . #processCached< { value : string | false } > ( ) (
623
+ this . #getPackageKey( packageName , "deprecation" ) ,
624
+ async ( ) => {
625
+ try {
626
+ // npmjs.org in a GitHub cache, I know, but hey, let's put that under the fact that
627
+ // GitHub owns npmjs.org okay??
628
+ const res = await fetch ( `https://registry.npmjs.org/${ packageName } /latest` ) ;
629
+ if ( res . status !== 200 ) return { } ;
630
+ return ( await res . json ( ) ) as { deprecated ?: boolean | string } ;
631
+ } catch ( error ) {
632
+ console . error ( `Error fetching npmjs.org for package ${ packageName } :` , error ) ;
633
+ return { } ;
634
+ }
635
+ } ,
636
+ ( { deprecated } ) => {
637
+ if ( deprecated === undefined ) return { value : false } ;
638
+ if ( typeof deprecated === "boolean" )
639
+ return { value : deprecated && "This package is deprecated" } ;
640
+ return { value : deprecated || "This package is deprecated" } ;
641
+ } ,
642
+ item => ( item . value === false ? DEPRECATIONS_TTL : undefined )
643
+ ) ;
644
+ }
589
645
}
590
646
591
647
export const gitHubCache = new GitHubCache ( KV_REST_API_URL , KV_REST_API_TOKEN , GITHUB_TOKEN ) ;
0 commit comments