Commit8c09fb9unknown_key
fix(api-v2): PR list pagination — ?limit, ?offset (default 30, max 100)
fix(api-v2): PR list pagination — ?limit, ?offset (default 30, max 100) The pulls list endpoint was returning every PR in a repo unbounded, matching neither the issues endpoint contract (limit 30 / max 100 / offset-based) nor any sensible API hygiene. A spec review flagged it as a likely API-latency / process-crash trigger for any repo with thousands of PRs. Same defaults as issues + commits to keep the API surface consistent across resource types. Bounds the limit to [1, 100] so a buggy client can't accidentally pull the whole table.
1 file changed+8−18c09fb95211c27a073b38f47162e96ae3338af20
1 changed file+8−1
Modifiedsrc/routes/api-v2.ts+8−1View fileUnifiedSplit
@@ -663,6 +663,11 @@ apiv2.post("/repos/:owner/:repo/issues/:number/comments", requireApiAuth, requir
663663apiv2.get("/repos/:owner/:repo/pulls", async (c) => {
664664 const { owner, repo } = c.req.param();
665665 const state = c.req.query("state") || "open";
666 // Match the issue-list pagination contract: default 30, max 100,
667 // 0-indexed offset for cursor-style scrolling. Bounded so a buggy
668 // client can't accidentally pull the whole table.
669 const limit = Math.min(100, Math.max(1, Number(c.req.query("limit")) || 30));
670 const offset = Math.max(0, Number(c.req.query("offset")) || 0);
666671
667672 const resolved = await resolveRepo(owner, repo);
668673 if (!resolved) return c.json({ error: "Not found" }, 404);
@@ -675,7 +680,9 @@ apiv2.get("/repos/:owner/:repo/pulls", async (c) => {
675680 .from(pullRequests)
676681 .innerJoin(users, eq(pullRequests.authorId, users.id))
677682 .where(and(eq(pullRequests.repositoryId, (resolved.repo as any).id), eq(pullRequests.state, state)))
678 .orderBy(desc(pullRequests.createdAt));
683 .orderBy(desc(pullRequests.createdAt))
684 .limit(limit)
685 .offset(offset);
679686
680687 return c.json(prList.map(({ pr, author }) => ({ ...pr, author })));
681688});
682689