@@ -65,7 +65,27 @@ export const diagnoseGitHubSetup = () => {
6565 } ;
6666} ;
6767
68- export interface GitHubResult < T = any > {
68+ interface GitHubApiResponse {
69+ [ key : string ] : unknown ;
70+ }
71+
72+ export interface GitHubIssue extends GitHubApiResponse {
73+ number : number ;
74+ title ?: string ;
75+ state ?: string ;
76+ html_url ?: string ;
77+ body ?: string ;
78+ labels ?: unknown [ ] ;
79+ }
80+
81+ export interface GitHubComment extends GitHubApiResponse {
82+ id : number ;
83+ body ?: string ;
84+ user ?: { login ?: string } ;
85+ created_at ?: string ;
86+ }
87+
88+ export interface GitHubResult < T = GitHubApiResponse > {
6989 success : boolean ;
7090 data ?: T ;
7191 error ?: string ;
@@ -81,7 +101,7 @@ export interface GitHubIssueSummary {
81101 labels : unknown [ ] ;
82102}
83103
84- async function githubProxyRequest ( method : string , endpoint : string , data ?: any ) : Promise < any > {
104+ async function githubProxyRequest ( method : string , endpoint : string , data ?: unknown ) : Promise < GitHubApiResponse > {
85105 const token = getStoredToken ( ) ;
86106 if ( ! token ) {
87107 throw new Error ( 'Not authenticated with GitHub' ) ;
@@ -141,18 +161,18 @@ const base64DecodeUtf8 = (input: string): string => {
141161 return decodeURIComponent ( escape ( atob ( input ) ) ) ;
142162} ;
143163
144- const getLabelNames = ( issue : any ) : string [ ] => {
164+ const getLabelNames = ( issue : GitHubApiResponse ) : string [ ] => {
145165 const labels = issue ?. labels ;
146166 if ( ! Array . isArray ( labels ) ) return [ ] ;
147167 return labels
148- . map ( ( l : any ) => ( typeof l === 'string' ? l : l ?. name ) )
149- . filter ( ( n : any ) => typeof n === 'string' ) ;
168+ . map ( ( l : unknown ) => ( typeof l === 'string' ? l : ( l as Record < string , unknown > ) ?. name ) )
169+ . filter ( ( n : unknown ) : n is string => typeof n === 'string' ) ;
150170} ;
151171
152- const issueHasAnyVersion = ( issue : any ) : boolean => {
172+ const issueHasAnyVersion = ( issue : GitHubApiResponse ) : boolean => {
153173 const labelNames = getLabelNames ( issue ) ;
154174 if ( labelNames . some ( ( n ) => n . startsWith ( 'version:' ) ) ) return true ;
155- const body : string = issue ?. body || '' ;
175+ const body : string = ( issue ?. body as string ) || '' ;
156176 return body . includes ( 'Version:' ) ;
157177} ;
158178
@@ -206,26 +226,26 @@ export const githubAdapter = {
206226 // ignore label failures
207227 }
208228
209- return { success : true , data } ;
210- } catch ( e : any ) {
211- return { success : false , error : e ?. message || 'Failed to create issue' } ;
229+ return { success : true , data : data as { number : number ; html_url : string } } ;
230+ } catch ( e : unknown ) {
231+ return { success : false , error : ( e as Error ) ?. message || 'Failed to create issue' } ;
212232 }
213233 } ,
214234
215- async createComment ( issueNumber : number , body : string ) : Promise < GitHubResult > {
235+ async createComment ( issueNumber : number , body : string ) : Promise < GitHubResult < GitHubApiResponse > > {
216236 if ( ! isGitHubConfigured ( ) ) return { success : false , error : 'Please sign in with GitHub' } ;
217237 const owner = getEnv ( 'VITE_GITHUB_OWNER' ) ;
218238 const repo = getEnv ( 'VITE_GITHUB_REPO' ) ;
219239
220240 try {
221241 const data = await githubProxyRequest ( 'POST' , `/repos/${ owner } /${ repo } /issues/${ issueNumber } /comments` , { body } ) ;
222242 return { success : true , data } ;
223- } catch ( e : any ) {
224- return { success : false , error : e ?. message || 'Failed to create comment' } ;
243+ } catch ( e : unknown ) {
244+ return { success : false , error : ( e as Error ) ?. message || 'Failed to create comment' } ;
225245 }
226246 } ,
227247
228- async fetchIssuesForRoute ( route : string ) : Promise < GitHubResult < any [ ] > > {
248+ async fetchIssuesForRoute ( route : string ) : Promise < GitHubResult < GitHubIssue [ ] > > {
229249 return githubAdapter . fetchIssuesForRouteAndVersion ( route ) ;
230250 } ,
231251
@@ -246,12 +266,12 @@ export const githubAdapter = {
246266 labels : Array . isArray ( data . labels ) ? data . labels : [ ] ,
247267 } ,
248268 } ;
249- } catch ( e : any ) {
250- return { success : false , error : e ?. message || 'Failed to fetch issue' } ;
269+ } catch ( e : unknown ) {
270+ return { success : false , error : ( e as Error ) ?. message || 'Failed to fetch issue' } ;
251271 }
252272 } ,
253273
254- async fetchIssuesForRouteAndVersion ( route : string , version ?: string ) : Promise < GitHubResult < any [ ] > > {
274+ async fetchIssuesForRouteAndVersion ( route : string , version ?: string ) : Promise < GitHubResult < GitHubIssue [ ] > > {
255275 if ( ! isGitHubConfigured ( ) ) return { success : false , error : 'Please sign in with GitHub' } ;
256276 const owner = getEnv ( 'VITE_GITHUB_OWNER' ) ;
257277 const repo = getEnv ( 'VITE_GITHUB_REPO' ) ;
@@ -262,18 +282,18 @@ export const githubAdapter = {
262282 ) ;
263283 // Filter by metadata OR labels (route:${route}), and optionally by version
264284 const filtered = ( Array . isArray ( data ) ? data : [ ] )
265- . filter ( ( issue : any ) => {
266- const body : string = issue ?. body || '' ;
285+ . filter ( ( issue : GitHubApiResponse ) => {
286+ const body : string = ( issue ?. body as string ) || '' ;
267287 const labels = getLabelNames ( issue ) ;
268288 const bodyMatch = body . includes ( `Route: \`${ route } \`` ) ;
269289 const labelMatch = labels . includes ( `route:${ route } ` ) ;
270290 return bodyMatch || labelMatch ;
271291 } )
272- . filter ( ( issue : any ) => {
292+ . filter ( ( issue : GitHubApiResponse ) => {
273293 if ( ! version ) return true ;
274294
275295 const labels = getLabelNames ( issue ) ;
276- const body : string = issue ?. body || '' ;
296+ const body : string = ( issue ?. body as string ) || '' ;
277297 const versionLabelMatch = labels . includes ( `version:${ version } ` ) ;
278298 const bodyVersionMatch = body . includes ( `Version: \`${ version } \`` ) ;
279299
@@ -282,13 +302,13 @@ export const githubAdapter = {
282302
283303 return versionLabelMatch || bodyVersionMatch ;
284304 } ) ;
285- return { success : true , data : filtered } ;
286- } catch ( e : any ) {
287- return { success : false , error : e ?. message || 'Failed to fetch issues' } ;
305+ return { success : true , data : filtered as GitHubIssue [ ] } ;
306+ } catch ( e : unknown ) {
307+ return { success : false , error : ( e as Error ) ?. message || 'Failed to fetch issues' } ;
288308 }
289309 } ,
290310
291- async fetchIssueComments ( issueNumber : number ) : Promise < GitHubResult < any [ ] > > {
311+ async fetchIssueComments ( issueNumber : number ) : Promise < GitHubResult < GitHubComment [ ] > > {
292312 if ( ! isGitHubConfigured ( ) ) return { success : false , error : 'Please sign in with GitHub' } ;
293313 const owner = getEnv ( 'VITE_GITHUB_OWNER' ) ;
294314 const repo = getEnv ( 'VITE_GITHUB_REPO' ) ;
@@ -297,57 +317,57 @@ export const githubAdapter = {
297317 'GET' ,
298318 `/repos/${ owner } /${ repo } /issues/${ issueNumber } /comments?per_page=100` ,
299319 ) ;
300- return { success : true , data } ;
301- } catch ( e : any ) {
302- return { success : false , error : e ?. message || 'Failed to fetch issue comments' } ;
320+ return { success : true , data : data as unknown as GitHubComment [ ] } ;
321+ } catch ( e : unknown ) {
322+ return { success : false , error : ( e as Error ) ?. message || 'Failed to fetch issue comments' } ;
303323 }
304324 } ,
305325
306- async updateComment ( commentId : number , body : string ) : Promise < GitHubResult > {
326+ async updateComment ( commentId : number , body : string ) : Promise < GitHubResult < GitHubApiResponse > > {
307327 if ( ! isGitHubConfigured ( ) ) return { success : false , error : 'Please sign in with GitHub' } ;
308328 const owner = getEnv ( 'VITE_GITHUB_OWNER' ) ;
309329 const repo = getEnv ( 'VITE_GITHUB_REPO' ) ;
310330 try {
311331 const data = await githubProxyRequest ( 'PATCH' , `/repos/${ owner } /${ repo } /issues/comments/${ commentId } ` , { body } ) ;
312332 return { success : true , data } ;
313- } catch ( e : any ) {
314- return { success : false , error : e ?. message || 'Failed to update comment' } ;
333+ } catch ( e : unknown ) {
334+ return { success : false , error : ( e as Error ) ?. message || 'Failed to update comment' } ;
315335 }
316336 } ,
317337
318- async deleteComment ( commentId : number ) : Promise < GitHubResult > {
338+ async deleteComment ( commentId : number ) : Promise < GitHubResult < GitHubApiResponse > > {
319339 if ( ! isGitHubConfigured ( ) ) return { success : false , error : 'Please sign in with GitHub' } ;
320340 const owner = getEnv ( 'VITE_GITHUB_OWNER' ) ;
321341 const repo = getEnv ( 'VITE_GITHUB_REPO' ) ;
322342 try {
323343 await githubProxyRequest ( 'DELETE' , `/repos/${ owner } /${ repo } /issues/comments/${ commentId } ` ) ;
324344 return { success : true , data : { } } ;
325- } catch ( e : any ) {
326- return { success : false , error : e ?. message || 'Failed to delete comment' } ;
345+ } catch ( e : unknown ) {
346+ return { success : false , error : ( e as Error ) ?. message || 'Failed to delete comment' } ;
327347 }
328348 } ,
329349
330- async closeIssue ( issueNumber : number ) : Promise < GitHubResult > {
350+ async closeIssue ( issueNumber : number ) : Promise < GitHubResult < GitHubApiResponse > > {
331351 if ( ! isGitHubConfigured ( ) ) return { success : false , error : 'Please sign in with GitHub' } ;
332352 const owner = getEnv ( 'VITE_GITHUB_OWNER' ) ;
333353 const repo = getEnv ( 'VITE_GITHUB_REPO' ) ;
334354 try {
335355 const data = await githubProxyRequest ( 'PATCH' , `/repos/${ owner } /${ repo } /issues/${ issueNumber } ` , { state : 'closed' } ) ;
336356 return { success : true , data } ;
337- } catch ( e : any ) {
338- return { success : false , error : e ?. message || 'Failed to close issue' } ;
357+ } catch ( e : unknown ) {
358+ return { success : false , error : ( e as Error ) ?. message || 'Failed to close issue' } ;
339359 }
340360 } ,
341361
342- async reopenIssue ( issueNumber : number ) : Promise < GitHubResult > {
362+ async reopenIssue ( issueNumber : number ) : Promise < GitHubResult < GitHubApiResponse > > {
343363 if ( ! isGitHubConfigured ( ) ) return { success : false , error : 'Please sign in with GitHub' } ;
344364 const owner = getEnv ( 'VITE_GITHUB_OWNER' ) ;
345365 const repo = getEnv ( 'VITE_GITHUB_REPO' ) ;
346366 try {
347367 const data = await githubProxyRequest ( 'PATCH' , `/repos/${ owner } /${ repo } /issues/${ issueNumber } ` , { state : 'open' } ) ;
348368 return { success : true , data } ;
349- } catch ( e : any ) {
350- return { success : false , error : e ?. message || 'Failed to reopen issue' } ;
369+ } catch ( e : unknown ) {
370+ return { success : false , error : ( e as Error ) ?. message || 'Failed to reopen issue' } ;
351371 }
352372 } ,
353373
@@ -357,17 +377,17 @@ export const githubAdapter = {
357377 const repo = getEnv ( 'VITE_GITHUB_REPO' ) ;
358378 try {
359379 const data = await githubProxyRequest ( 'GET' , `/repos/${ owner } /${ repo } /contents/${ encodePath ( path ) } ` ) ;
360- const content = typeof data ? .content === 'string' ? data . content . replace ( / \n / g, '' ) : '' ;
361- const sha = data ? .sha as string | undefined ;
380+ const content = typeof data . content === 'string' ? data . content . replace ( / \n / g, '' ) : '' ;
381+ const sha = data . sha as string | undefined ;
362382 if ( ! content || ! sha ) return { success : true , data : null } ;
363383 const text = base64DecodeUtf8 ( content ) ;
364384 return { success : true , data : { text, sha } } ;
365- } catch ( e : any ) {
385+ } catch ( e : unknown ) {
366386 // If file doesn't exist yet, treat as empty
367- if ( String ( e ?. message || '' ) . toLowerCase ( ) . includes ( 'not found' ) ) {
387+ if ( String ( ( e as Error ) ?. message || '' ) . toLowerCase ( ) . includes ( 'not found' ) ) {
368388 return { success : true , data : null } ;
369389 }
370- return { success : false , error : e ?. message || 'Failed to read repo file' } ;
390+ return { success : false , error : ( e as Error ) ?. message || 'Failed to read repo file' } ;
371391 }
372392 } ,
373393
@@ -381,7 +401,7 @@ export const githubAdapter = {
381401 const owner = getEnv ( 'VITE_GITHUB_OWNER' ) ;
382402 const repo = getEnv ( 'VITE_GITHUB_REPO' ) ;
383403 try {
384- const payload : any = {
404+ const payload : Record < string , string > = {
385405 message : params . message ,
386406 content : base64EncodeUtf8 ( params . text ) ,
387407 } ;
@@ -391,10 +411,10 @@ export const githubAdapter = {
391411 `/repos/${ owner } /${ repo } /contents/${ encodePath ( params . path ) } ` ,
392412 payload ,
393413 ) ;
394- const newSha = data ? .content ?. sha as string | undefined ;
414+ const newSha = ( ( data as { content ?: { sha ?: string } } ) . content ?. sha ) as string | undefined ;
395415 return { success : true , data : { sha : newSha || params . sha || '' } } ;
396- } catch ( e : any ) {
397- return { success : false , error : e ?. message || 'Failed to write repo file' } ;
416+ } catch ( e : unknown ) {
417+ return { success : false , error : ( e as Error ) ?. message || 'Failed to write repo file' } ;
398418 }
399419 } ,
400420} ;
0 commit comments