@rmdes/indiekit-endpoint-github 1.2.6 → 1.2.7
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/index.js +18 -7
- package/lib/controllers/activity.js +4 -4
- package/lib/controllers/changelog.js +1 -10
- package/lib/controllers/stars.js +4 -4
- package/lib/github-client.js +18 -30
- package/package.json +2 -1
package/index.js
CHANGED
|
@@ -2,6 +2,8 @@ import express from "express";
|
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
|
|
5
|
+
import { waitForReady } from "@rmdes/indiekit-startup-gate";
|
|
6
|
+
|
|
5
7
|
import { activityController } from "./lib/controllers/activity.js";
|
|
6
8
|
import { changelogController } from "./lib/controllers/changelog.js";
|
|
7
9
|
import { commitsController } from "./lib/controllers/commits.js";
|
|
@@ -115,13 +117,22 @@ export default class GitHubEndpoint {
|
|
|
115
117
|
|
|
116
118
|
// Start background sync for starred repos (if token + DB available)
|
|
117
119
|
if (this.options.token && Indiekit.database) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
120
|
+
this._stopGate = waitForReady(
|
|
121
|
+
() => {
|
|
122
|
+
import("./lib/starred-sync.js")
|
|
123
|
+
.then(({ startStarredSync }) => {
|
|
124
|
+
startStarredSync(Indiekit, this.options);
|
|
125
|
+
})
|
|
126
|
+
.catch((error) => {
|
|
127
|
+
console.error("[GitHub Stars] Sync scheduler failed to start:", error.message);
|
|
128
|
+
});
|
|
129
|
+
},
|
|
130
|
+
{ label: "GitHub" },
|
|
131
|
+
);
|
|
125
132
|
}
|
|
126
133
|
}
|
|
134
|
+
|
|
135
|
+
destroy() {
|
|
136
|
+
this._stopGate?.();
|
|
137
|
+
}
|
|
127
138
|
}
|
|
@@ -109,16 +109,16 @@ export const activityController = {
|
|
|
109
109
|
activity = utils.extractRepoActivity(events, username);
|
|
110
110
|
}
|
|
111
111
|
} catch (apiError) {
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
return response
|
|
113
|
+
.status(apiError.status || 500)
|
|
114
|
+
.json({ error: apiError.message });
|
|
114
115
|
}
|
|
115
116
|
|
|
116
117
|
activity = activity.slice(0, limits.activity);
|
|
117
118
|
|
|
118
119
|
response.json({ activity });
|
|
119
120
|
} catch (error) {
|
|
120
|
-
|
|
121
|
-
response.json({ activity: [], error: "GitHub API temporarily unavailable" });
|
|
121
|
+
next(error);
|
|
122
122
|
}
|
|
123
123
|
},
|
|
124
124
|
};
|
|
@@ -206,16 +206,7 @@ export const changelogController = {
|
|
|
206
206
|
generatedAt: new Date().toISOString(),
|
|
207
207
|
});
|
|
208
208
|
} catch (error) {
|
|
209
|
-
|
|
210
|
-
response.json({
|
|
211
|
-
commits: [],
|
|
212
|
-
categories: {},
|
|
213
|
-
commitCategories: {},
|
|
214
|
-
totalCommits: 0,
|
|
215
|
-
days: daysValue || 30,
|
|
216
|
-
generatedAt: new Date().toISOString(),
|
|
217
|
-
error: "GitHub API temporarily unavailable",
|
|
218
|
-
});
|
|
209
|
+
next(error);
|
|
219
210
|
}
|
|
220
211
|
},
|
|
221
212
|
};
|
package/lib/controllers/stars.js
CHANGED
|
@@ -69,16 +69,16 @@ export const starsController = {
|
|
|
69
69
|
try {
|
|
70
70
|
starred = await client.getUserStarred(username, limits.stars);
|
|
71
71
|
} catch (apiError) {
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
return response
|
|
73
|
+
.status(apiError.status || 500)
|
|
74
|
+
.json({ error: apiError.message });
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
const stars = utils.formatStarred(starred);
|
|
77
78
|
|
|
78
79
|
response.json({ stars });
|
|
79
80
|
} catch (error) {
|
|
80
|
-
|
|
81
|
-
response.json({ stars: [], error: "GitHub API temporarily unavailable" });
|
|
81
|
+
next(error);
|
|
82
82
|
}
|
|
83
83
|
},
|
|
84
84
|
};
|
package/lib/github-client.js
CHANGED
|
@@ -22,7 +22,7 @@ export class GitHubClient {
|
|
|
22
22
|
async fetch(endpoint) {
|
|
23
23
|
const url = `${BASE_URL}${endpoint}`;
|
|
24
24
|
|
|
25
|
-
// Check cache first
|
|
25
|
+
// Check cache first
|
|
26
26
|
const cached = this.cache.get(url);
|
|
27
27
|
if (cached && Date.now() - cached.timestamp < this.cacheTtl) {
|
|
28
28
|
return cached.data;
|
|
@@ -37,40 +37,28 @@ export class GitHubClient {
|
|
|
37
37
|
headers.Authorization = `Bearer ${this.token}`;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
throw await IndiekitError.fromFetch(response);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
throw new IndiekitError(response.statusText, {
|
|
52
|
-
status: response.status,
|
|
53
|
-
code: response.statusText,
|
|
54
|
-
});
|
|
40
|
+
const response = await fetch(url, { headers });
|
|
41
|
+
|
|
42
|
+
if (!response.ok) {
|
|
43
|
+
// Only use fromFetch for JSON error responses; GitHub sometimes returns
|
|
44
|
+
// HTML error pages (e.g., 502 Bad Gateway) which cause SyntaxError noise
|
|
45
|
+
const contentType = response.headers.get("content-type") || "";
|
|
46
|
+
if (contentType.includes("json")) {
|
|
47
|
+
throw await IndiekitError.fromFetch(response);
|
|
55
48
|
}
|
|
56
49
|
|
|
57
|
-
|
|
50
|
+
throw new IndiekitError(response.statusText, {
|
|
51
|
+
status: response.status,
|
|
52
|
+
code: response.statusText,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
58
55
|
|
|
59
|
-
|
|
60
|
-
this.cache.set(url, { data, timestamp: Date.now() });
|
|
56
|
+
const data = await response.json();
|
|
61
57
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
// Stale-while-error: if we have stale cached data, return it
|
|
65
|
-
if (cached) {
|
|
66
|
-
console.warn(
|
|
67
|
-
`[GitHub] API error for ${endpoint}: ${error.message}. Serving stale cache (age: ${Math.round((Date.now() - cached.timestamp) / 60_000)}min)`,
|
|
68
|
-
);
|
|
69
|
-
return cached.data;
|
|
70
|
-
}
|
|
58
|
+
// Cache result
|
|
59
|
+
this.cache.set(url, { data, timestamp: Date.now() });
|
|
71
60
|
|
|
72
|
-
|
|
73
|
-
}
|
|
61
|
+
return data;
|
|
74
62
|
}
|
|
75
63
|
|
|
76
64
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rmdes/indiekit-endpoint-github",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.7",
|
|
4
4
|
"description": "GitHub activity endpoint for Indiekit. Display commits, stars, contributions, and featured repositories.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"indiekit",
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@indiekit/error": "^1.0.0-beta.25",
|
|
43
|
+
"@rmdes/indiekit-startup-gate": "^1.0.0",
|
|
43
44
|
"express": "^5.0.0"
|
|
44
45
|
},
|
|
45
46
|
"peerDependencies": {
|