@rmdes/indiekit-endpoint-github 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,60 @@
1
1
  import { GitHubClient } from "../github-client.js";
2
2
  import * as utils from "../utils.js";
3
3
 
4
+ /**
5
+ * Fetch commits from user's recently pushed repos
6
+ * Used as fallback when Events API doesn't include commit details
7
+ * @param {GitHubClient} client - GitHub client
8
+ * @param {string} username - GitHub username
9
+ * @param {number} limit - Max commits to return
10
+ * @returns {Promise<Array>} - Formatted commits
11
+ */
12
+ async function fetchCommitsFromRepos(client, username, limit = 10) {
13
+ try {
14
+ // Get user's recently pushed repos (sorted by push date)
15
+ const repos = await client.getUserRepos(username, 8, "pushed");
16
+
17
+ if (!Array.isArray(repos) || repos.length === 0) {
18
+ return [];
19
+ }
20
+
21
+ // Fetch recent commits from each repo in parallel
22
+ const commitPromises = repos.slice(0, 5).map(async (repo) => {
23
+ try {
24
+ const repoCommits = await client.getRepoCommits(
25
+ repo.owner?.login || username,
26
+ repo.name,
27
+ 5,
28
+ );
29
+
30
+ return repoCommits.map((c) => ({
31
+ sha: c.sha.slice(0, 7),
32
+ message: utils.truncate(c.commit?.message?.split("\n")[0]),
33
+ url: c.html_url,
34
+ repo: repo.full_name,
35
+ repoUrl: repo.html_url,
36
+ date: c.commit?.author?.date || c.commit?.committer?.date,
37
+ author: c.commit?.author?.name,
38
+ }));
39
+ } catch {
40
+ // Skip repos we can't access (private without token, etc.)
41
+ return [];
42
+ }
43
+ });
44
+
45
+ const commitResults = await Promise.all(commitPromises);
46
+ const allCommits = commitResults.flat();
47
+
48
+ // Sort by date descending and return limited results
49
+ return allCommits
50
+ .toSorted((a, b) => new Date(b.date) - new Date(a.date))
51
+ .slice(0, limit);
52
+ } catch (error) {
53
+ console.error("[commits] Error fetching from repos:", error.message);
54
+ return [];
55
+ }
56
+ }
57
+
4
58
  /**
5
59
  * Display commits list
6
60
  * @type {import("express").RequestHandler}
@@ -20,23 +74,26 @@ export const commitsController = {
20
74
 
21
75
  const client = new GitHubClient({ token, cacheTtl });
22
76
 
23
- let events = [];
77
+ // Try events API first (includes commits when GitHub provides them)
78
+ let commits = [];
24
79
  try {
25
- events = await client.getUserEvents(username, 100);
80
+ const events = await client.getUserEvents(username, 100);
81
+ commits = utils.extractCommits(events);
26
82
  } catch (apiError) {
27
- console.error("GitHub API error:", apiError);
28
- return response.render("commits", {
29
- title: response.locals.__("github.commits.title"),
30
- actions: [],
31
- parent: {
32
- href: request.baseUrl,
33
- text: response.locals.__("github.title"),
34
- },
35
- error: { message: apiError.message || "Failed to fetch commits" },
36
- });
83
+ console.error("[commits] GitHub Events API error:", apiError.message);
37
84
  }
38
85
 
39
- const commits = utils.extractCommits(events).slice(0, limits.commits * 3);
86
+ // Fallback: fetch commits directly from repos if events didn't have them
87
+ if (commits.length === 0) {
88
+ console.log(
89
+ "[commits] Events API returned no commits, fetching from repos",
90
+ );
91
+ commits = await fetchCommitsFromRepos(
92
+ client,
93
+ username,
94
+ limits.commits * 3,
95
+ );
96
+ }
40
97
 
41
98
  response.render("commits", {
42
99
  title: response.locals.__("github.commits.title"),
@@ -45,7 +102,7 @@ export const commitsController = {
45
102
  href: request.baseUrl,
46
103
  text: response.locals.__("github.title"),
47
104
  },
48
- commits,
105
+ commits: commits.slice(0, limits.commits * 3),
49
106
  username,
50
107
  mountPath: request.baseUrl,
51
108
  });
@@ -65,18 +122,24 @@ export const commitsController = {
65
122
 
66
123
  const client = new GitHubClient({ token, cacheTtl });
67
124
 
68
- let events = [];
125
+ // Try events API first (includes commits when GitHub provides them)
126
+ let commits = [];
69
127
  try {
70
- events = await client.getUserEvents(username, 50);
128
+ const events = await client.getUserEvents(username, 50);
129
+ commits = utils.extractCommits(events);
71
130
  } catch (apiError) {
72
- return response
73
- .status(apiError.status || 500)
74
- .json({ error: apiError.message });
131
+ console.log("[commits API] Events API error:", apiError.message);
75
132
  }
76
133
 
77
- const commits = utils.extractCommits(events).slice(0, limits.commits);
134
+ // Fallback: fetch commits directly from repos if events didn't have them
135
+ if (commits.length === 0) {
136
+ console.log(
137
+ "[commits API] Events API returned no commits, fetching from repos",
138
+ );
139
+ commits = await fetchCommitsFromRepos(client, username, limits.commits);
140
+ }
78
141
 
79
- response.json({ commits });
142
+ response.json({ commits: commits.slice(0, limits.commits) });
80
143
  } catch (error) {
81
144
  next(error);
82
145
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rmdes/indiekit-endpoint-github",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "GitHub activity endpoint for Indiekit. Display commits, stars, contributions, and featured repositories.",
5
5
  "keywords": [
6
6
  "indiekit",