Subject: [PATCH links] Fetch all tags, via cursor pagintion, for the Pinboard API bridge.

From: Peter Sanchez <[email-masked]>
Date: Wed, 13 Aug 2025 08:08:23 -0600

Changelog-updated: The `/pinboard/tags/get` endpoint will now fetch all
  tags via cursor pagination
---
 pinboard/routes.go | 58 +++++++++++++++++++++++++++++++++-------------
 1 file changed, 42 insertions(+), 16 deletions(-)

diff --git a/pinboard/routes.go b/pinboard/routes.go
index 69c1311..5393056 100644
--- a/pinboard/routes.go
+++ b/pinboard/routes.go
@@ -781,31 +781,57 @@ func (s *Service) TagsGet(c echo.Context) error {
 	// Prepare GraphQL query
 	type GraphQLResponse struct {
 		GetTags struct {
-			Result []*models.Tag `json:"result"`
+			Result   []*models.Tag `json:"result"`
+			PageInfo struct {
+				Cursor      string `json:"cursor"`
+				HasNextPage bool   `json:"hasNextPage"`
+			} `json:"pageInfo"`
 		} `json:"getTags"`
 	}
 
-	var result GraphQLResponse
-	op := gqlclient.NewOperation(
-		`query GetTags($orgSlug: String!) {
-			getTags(input: {orgSlug: $orgSlug}) {
-				result {
-					name
-					count
+	// Collect all tags across all pages
+	var allTags []*models.Tag
+	var afterCursor *string
+
+	// Loop through all pages
+	for {
+		var result GraphQLResponse
+		op := gqlclient.NewOperation(
+			`query GetTags($orgSlug: String!, $limit: Int, $after: Cursor) {
+				getTags(input: {orgSlug: $orgSlug, limit: $limit, after: $after}) {
+					result {
+						name
+						count
+					}
+					pageInfo {
+						cursor
+						hasNextPage
+					}
 				}
-			}
-		}`)
+			}`)
 
-	op.Var("orgSlug", org.Slug)
+		op.Var("orgSlug", org.Slug)
+		op.Var("limit", 250) // Maximum tags per call
+		if afterCursor != nil {
+			op.Var("after", *afterCursor)
+		}
 
-	err = links.Execute(c.Request().Context(), op, &result)
-	if err != nil {
-		return formatError(c, err.Error())
+		err = links.Execute(c.Request().Context(), op, &result)
+		if err != nil {
+			return formatError(c, err.Error())
+		}
+
+		allTags = append(allTags, result.GetTags.Result...)
+
+		if !result.GetTags.PageInfo.HasNextPage {
+			break
+		}
+		afterCursor = &result.GetTags.PageInfo.Cursor
 	}
 
 	// Convert to Pinboard format
-	tags := make([]PinboardTag, len(result.GetTags.Result))
-	for i, tag := range result.GetTags.Result {
+	tags := make([]PinboardTag, len(allTags))
+	for i, tag := range allTags {
 		tags[i] = PinboardTag{
 			Tag:   tag.Name,
 			Count: tag.Count,
-- 
2.49.1

---

From: "Peter Sanchez" <[email-masked]>
Date: Wed, 13 Aug 2025 16:12:52 -0600

Applied.

To [email-masked]:~netlandish/links
   fc98b6e..d329c96  master -> master