Commit ddbcfc8

Anton Medvedev <anton@medv.io>
2024-07-07 10:53:21
Add starredRepositories query
1 parent 7aca563
Changed files (3)
src/collect/collect.ts
@@ -10,6 +10,7 @@ import {
   discussionCommentsQuery,
   DiscussionCommentsQuery,
 } from './discussion-comments.js'
+import { starsQuery, StarsQuery } from './stars.js'
 
 export async function collect(
   octokit: Octokit,
@@ -21,6 +22,7 @@ export async function collect(
 
   const data: Data = {
     user: user,
+    starredRepositories: [],
     repos: [],
     pulls: [],
     issues: [],
@@ -199,5 +201,22 @@ export async function collect(
     console.error(err)
   }
 
+  const stars = octokit.graphql.paginate.iterator<StarsQuery>(starsQuery, {
+    login: username,
+  })
+  try {
+    for await (const resp of stars) {
+      for (const repo of resp.user.starredRepositories.nodes) {
+        data.starredRepositories.push(repo)
+      }
+      console.log(
+        `| stars ${data.starredRepositories.length}/${resp.user.starredRepositories.totalCount} (cost: ${resp.rateLimit.cost}, remaining: ${resp.rateLimit.remaining})`,
+      )
+    }
+  } catch (err) {
+    console.error(`Failed to load stars`)
+    console.error(err)
+  }
+
   return data
 }
src/collect/stars.ts
@@ -0,0 +1,79 @@
+export const starsQuery = `#graphql
+query StarsQuery($login: String!, $num: Int = 100, $cursor: String) {
+  user(login: $login) {
+    starredRepositories(first: $num, after: $cursor) {
+      totalCount
+      isOverLimit
+      nodes {
+        nameWithOwner
+        description
+        stargazers {
+          totalCount
+        }
+        languages(first: 10, orderBy: {field: SIZE, direction: DESC}) {
+          totalCount
+          edges {
+            size
+            node {
+              name
+            }
+          }
+        }
+        licenseInfo {
+          name
+          nickname
+        }
+      }
+      pageInfo {
+        hasNextPage
+        endCursor
+      }
+    }
+  }
+  rateLimit {
+    limit
+    cost
+    remaining
+    resetAt
+  }
+}
+`
+
+export type StarsQuery = {
+  user: {
+    starredRepositories: {
+      totalCount: number
+      isOverLimit: boolean
+      nodes: Array<{
+        nameWithOwner: string
+        description: string
+        stargazers: {
+          totalCount: number
+        }
+        languages: {
+          totalCount: number
+          edges: Array<{
+            size: number
+            node: {
+              name: string
+            }
+          }>
+        }
+        licenseInfo: {
+          name: string
+          nickname: string
+        }
+      }>
+      pageInfo: {
+        hasNextPage: boolean
+        endCursor: string
+      }
+    }
+  }
+  rateLimit: {
+    limit: number
+    cost: number
+    remaining: number
+    resetAt: string
+  }
+}
src/collect/types.ts
@@ -5,6 +5,7 @@ import { UserQuery } from './user.js'
 import { PullsQuery } from './pulls.js'
 import { IssueCommentsQuery } from './issue-comments.js'
 import { DiscussionCommentsQuery } from './discussion-comments.js'
+import { StarsQuery } from './stars.js'
 
 // Extra<T> represents additional data that is not returned by the GraphQL API,
 // but enriched by some other means (e.g., separate queries).
@@ -12,6 +13,7 @@ export type Extra<T> = T | undefined
 
 export type Data = {
   user: User
+  starredRepositories: StarredRepo[]
   repos: Repo[]
   pulls: Pull[]
   issues: Issue[]
@@ -38,3 +40,5 @@ export type IssueComment =
 
 export type DiscussionComment =
   DiscussionCommentsQuery['user']['repositoryDiscussionComments']['nodes'][0]
+
+export type StarredRepo = StarsQuery['user']['starredRepositories']['nodes'][0]