summaryrefslogtreecommitdiff
path: root/cgithub/src/app.ts
diff options
context:
space:
mode:
Diffstat (limited to 'cgithub/src/app.ts')
-rw-r--r--cgithub/src/app.ts46
1 files changed, 46 insertions, 0 deletions
diff --git a/cgithub/src/app.ts b/cgithub/src/app.ts
index 78b59ae..ca79b1f 100644
--- a/cgithub/src/app.ts
+++ b/cgithub/src/app.ts
@@ -5,8 +5,10 @@ import {
getGitHubBlob,
getGitHubCommits,
getGitHubIssues,
+ getGitHubLatestCommit,
getGitHubOwner,
getGitHubPulls,
+ getGitHubRefs,
getGitHubRelease,
getGitHubReleases,
getGitHubRepo,
@@ -44,6 +46,29 @@ export function createApp(eta: Eta) {
return c.html(eta.render(template, data));
}
+ // For fragments fetched asynchronously by client-side JS (see public/static/refs.js):
+ // errors render as an empty body rather than the full error.eta page.
+ async function tryRenderFragment<T extends object>(
+ c: Context,
+ template: string,
+ promise: Promise<T>,
+ ) {
+ let data: T;
+ try {
+ data = await promise;
+ } catch (e) {
+ const status =
+ e instanceof GitHubHTTPError
+ ? (e.status as StatusCode)
+ : e instanceof RedirectError
+ ? 404
+ : 500;
+ c.status(status);
+ return c.body(null);
+ }
+ return c.html(eta.render(template, data));
+ }
+
app.get("/:owner", async (c) => {
const { owner } = c.req.param();
return tryRender(c, "owner.eta", getGitHubOwner(owner));
@@ -112,6 +137,27 @@ export function createApp(eta: Eta) {
return tryRender(c, "commits.eta", getGitHubCommits(owner, repo, branch, path));
});
+ // Internal endpoints fetched asynchronously by client-side JS, not meant to
+ // be visited directly. Keep the site's initial page loads plain server-
+ // rendered HTML while still surfacing data (branches/tags, latest commit)
+ // that would otherwise require an extra scrape on every page view.
+ app.get("/api/:owner/:repo/refs/:type", async (c) => {
+ const { owner, repo, type } = c.req.param();
+ if (type !== "branches" && type !== "tags") {
+ return c.notFound();
+ }
+ return tryRenderFragment(c, "_refs.eta", getGitHubRefs(owner, repo, type));
+ });
+
+ app.get("/api/:owner/:repo/latest-commit/:branch/:path{.*}?", async (c) => {
+ const { owner, repo, branch, path = "" } = c.req.param();
+ return tryRenderFragment(
+ c,
+ "_latestCommit.eta",
+ getGitHubLatestCommit(owner, repo, branch, path),
+ );
+ });
+
app.get("/:owner/:repo/releases/tag/:tag", async (c) => {
const { owner, repo, tag } = c.req.param();
return tryRender(c, "release.eta", getGitHubRelease(owner, repo, tag));