import { Octokit } from '@octokit/rest' import type { Repository } from '../types/index.js' export class GitHubClient { private octokit: Octokit constructor(token: string) { this.octokit = new Octokit({ auth: token, }) } async getAuthenticatedUser() { const { data } = await this.octokit.users.getAuthenticated() return data } async getAllPublicRepositories(limit?: number): Promise { const repositories: Repository[] = [] let page = 1 const perPage = 100 while (true) { const { data } = await this.octokit.repos.listForAuthenticatedUser({ visibility: 'public', per_page: perPage, page, sort: 'updated', direction: 'desc', }) if (data.length === 0) break repositories.push(...(data as Repository[])) // Stop if we've reached the limit if (limit && repositories.length >= limit) { return repositories.slice(0, limit) } page++ } return repositories } async getLastCommitDate(owner: string, repo: string): Promise { try { const { data } = await this.octokit.repos.listCommits({ owner, repo, per_page: 1, }) if (data.length > 0 && data[0]?.commit?.author?.date) { return new Date(data[0].commit.author.date) } } catch (error: unknown) { // Ignore empty repository errors (409) if (error instanceof Error && 'status' in error && error.status !== 409) { console.error( `Failed to get commits for ${owner}/${repo}:`, error.message, ) } } return null } async makeRepositoryPrivate( owner: string, repo: string, dryRun = false, ): Promise { if (dryRun) { console.log(`[DRY RUN] Would make ${owner}/${repo} private`) return true } try { await this.octokit.repos.update({ owner, repo, private: true, }) return true } catch (error) { console.error(`Failed to update ${owner}/${repo}:`, error) return false } } }