@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.
- package/lib/controllers/commits.js +84 -21
- package/package.json +1 -1
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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