summaryrefslogtreecommitdiff
path: root/cgithub/src/app.ts
diff options
context:
space:
mode:
authorJoe Mou <dev@mou.fo>2026-09-09 11:03:02 -0400
committerJoe Mou <dev@mou.fo>2026-09-09 14:39:57 -0400
commita7bc82cad42b7b8c4c8c52e1217f7f005b632e6d (patch)
tree611468fa8b0cc02e7540dc870071bab941636e1b /cgithub/src/app.ts
parent484cdb8dbceb572e4b858c80109cb81b671fd2fd (diff)
Serve GitHub's global search when it names one repository
/search?q=repo:owner/name+...&type=code matched the /:owner route and rendered a profile page for an owner named "search", which GitHub 404s. It is the URL GitHub's own search box produces, so it arrives whenever a search is redirected here. A /search route now takes it: when the query carries a repo: qualifier and a type, it strips the qualifier and redirects to that repository's search route, which already maps issues and pull requests to pages we render and hands the rest to GitHub. Searches that name no single repository -- bare queries, org:/user: scopes, a missing type -- keep redirecting to github.com/search as they did before. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GkGX6puS45xD5KzdV9tHEA
Diffstat (limited to 'cgithub/src/app.ts')
-rw-r--r--cgithub/src/app.ts19
1 files changed, 19 insertions, 0 deletions
diff --git a/cgithub/src/app.ts b/cgithub/src/app.ts
index a040aaa..7e5e9e8 100644
--- a/cgithub/src/app.ts
+++ b/cgithub/src/app.ts
@@ -95,6 +95,25 @@ export function createApp(eta: Eta) {
return c.render("home.eta");
});
+ // GitHub's global search, which we only serve when it is scoped to a single
+ // repository: strip the qualifier and let that repository's search route
+ // decide what to do with the rest.
+ app.get("/search", async (c) => {
+ const q = c.req.query("q") ?? "";
+ const type = c.req.query("type");
+
+ const repoQualifier = /(?:^|\s)repo:([^/\s]+)\/([^/\s]+)(?=\s|$)/.exec(q);
+ if (type && repoQualifier) {
+ const [qualifier, owner, repo] = repoQualifier;
+ const rest =
+ q.slice(0, repoQualifier.index) + q.slice(repoQualifier.index + qualifier.length);
+ const params = new URLSearchParams({ q: rest.trim(), type });
+ return c.redirect(`/${owner}/${repo}/search?${params}`);
+ }
+
+ return redirectToGitHub(c);
+ });
+
app.get("/:owner", async (c) => {
const { owner } = c.req.param();
return c.render("owner.eta", await getGitHubOwner(owner));