(username: string, userToken?: string | null)
| 225 | } |
| 226 | |
| 227 | static async getFeatured(username: string, userToken?: string | null): Promise<ProjectsData> { |
| 228 | const token = userToken || Settings.GITHUB_TOKEN; |
| 229 | if (!token) { |
| 230 | throw new Error( |
| 231 | 'GITHUB_TOKEN is required. Please set it in your environment variables or authenticate.' |
| 232 | ); |
| 233 | } |
| 234 | |
| 235 | try { |
| 236 | const [allRepos, pinnedRepoNames] = await Promise.all([ |
| 237 | GitHubRepositoryFetcher.fetchAllRepositories(username, userToken), |
| 238 | GitHubRepositoryFetcher.fetchPinnedRepositories(username), |
| 239 | ]); |
| 240 | |
| 241 | const topScoredRepos = ProjectScorer.getTopProjects( |
| 242 | allRepos, |
| 243 | pinnedRepoNames, |
| 244 | 8 |
| 245 | ); |
| 246 | |
| 247 | const gqlRepoMap = await this.enrichRepositoriesWithGraphQL(username, userToken); |
| 248 | |
| 249 | const featured: FeaturedProject[] = topScoredRepos.map(repo => |
| 250 | this.convertToFeaturedProject(repo, gqlRepoMap.get(repo.name)) |
| 251 | ); |
| 252 | |
| 253 | const nonForkRepos = allRepos.filter( |
| 254 | repo => !repo.fork && !repo.archived && !repo.disabled |
| 255 | ); |
| 256 | |
| 257 | const totalStars = nonForkRepos.reduce( |
| 258 | (sum, repo) => sum + repo.stargazers_count, |
| 259 | 0 |
| 260 | ); |
| 261 | |
| 262 | const languages = LanguageRanker.getAllLanguages(nonForkRepos); |
| 263 | |
| 264 | return { |
| 265 | featured, |
| 266 | languages, |
| 267 | total_stars: totalStars, |
| 268 | total_repos: nonForkRepos.length, |
| 269 | }; |
| 270 | } catch (error: unknown) { |
| 271 | const errorMessage = error instanceof Error ? error.message : String(error); |
| 272 | throw new Error(`Failed to fetch projects: ${errorMessage}`); |
| 273 | } |
| 274 | } |
| 275 | } |
no test coverage detected