Documentation
¶
Overview ¶
Package ghclient is the desktop's own GitHub REST/GraphQL client: in-app authentication (OAuth device flow, PAT validation via User) and the typed API calls the connector needs (batched search, notifications, single-issue hydration). It owns no feed concepts — caching, polling cadence, and unread state live in cmd/desktop/internal/app/sources/github/feed — and no persistence: callers hold whatever token they have and pass it in via WithTokenCopy.
HTTP plumbing — the failure taxonomy, status mapping, conditional requests, request logging — comes from sources/sourcehttp.
Index ¶
- type BranchRef
- type CheckState
- type Client
- func (c *Client) ItemStates(ctx context.Context, refs []ItemRef) ([]ItemState, error)
- func (c *Client) Notifications(ctx context.Context, limit int, prev sourcehttp.Validators) (NotificationsResult, error)
- func (c *Client) PollDeviceFlow(ctx context.Context, clientID string, auth DeviceAuth) (string, error)
- func (c *Client) PullRequestsByBranch(ctx context.Context, refs []BranchRef) ([]PullRequest, error)
- func (c *Client) SearchIssuesBatch(ctx context.Context, reqs []SearchRequest) ([][]SearchItem, error)
- func (c *Client) StartDeviceFlow(ctx context.Context, clientID string, scopes []string) (DeviceAuth, error)
- func (c *Client) User(ctx context.Context) (User, error)
- func (c *Client) WithTokenCopy(token string) *Client
- type DeviceAuth
- type ItemRef
- type ItemState
- type Label
- type Notification
- type NotificationSubject
- type NotificationsResult
- type Option
- type PullRequest
- type Repository
- type ReviewState
- type SearchItem
- type SearchRequest
- type User
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CheckState ¶
type CheckState string
CheckState condenses a pull request's check rollup. GitHub reports one rollup state per commit, so unlike the CLI's per-check array there is nothing to fold together here.
const ( // CheckStateNone is a head commit with no checks configured. CheckStateNone CheckState = "" CheckStatePassing CheckState = "passing" CheckStatePending CheckState = "pending" CheckStateFailing CheckState = "failing" )
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a GitHub REST v3 / GraphQL client. The zero value is not usable; construct with NewClient.
func (*Client) ItemStates ¶
ItemStates resolves the current lifecycle state of each ref via a batched, aliased GraphQL query, chunked at itemStateChunk refs per request. out is always len(refs), including alongside an error: a failing chunk stops the rest, and the states already resolved are still in out.
A ref whose repository is deleted or private resolves to a null alias plus a NOT_FOUND error, which is tolerated: that ref comes back Found:false while the rest of its chunk resolves normally, so one gone repo cannot strand the whole batch.
func (*Client) Notifications ¶
func (c *Client) Notifications(ctx context.Context, limit int, prev sourcehttp.Validators) (NotificationsResult, error)
Notifications lists the user's notification inbox, including read threads, so the app can mirror the full inbox and keep triage state locally. Non-empty prev validators make the request conditional: authenticated 304 responses are free of rate-limit cost, so polling an unchanged inbox costs nothing.
func (*Client) PollDeviceFlow ¶
func (c *Client) PollDeviceFlow(ctx context.Context, clientID string, auth DeviceAuth) (string, error)
PollDeviceFlow polls the token endpoint until the user authorizes the device, the code expires, or ctx is canceled. It blocks; run it in a goroutine and honor ctx for cancellation.
func (*Client) PullRequestsByBranch ¶
PullRequestsByBranch resolves each ref's pull request in a single GraphQL request, aliased so out[i] answers refs[i].
A repository the token cannot see resolves to a null alias rather than failing the batch (postGraphQL's tolerateNotFound), and reports Found: false like a branch with no pull request. A transport or auth failure is what arrives as an error, for the whole batch.
func (*Client) SearchIssuesBatch ¶
func (c *Client) SearchIssuesBatch(ctx context.Context, reqs []SearchRequest) ([][]SearchItem, error)
SearchIssuesBatch runs requests as aliased search fields, newest-updated first. GitHub times out when statusCheckRollup is resolved for large search batches, so each request carries at most two aliases with pages of 25. Results map back by request index: out[i] answers reqs[i].
func (*Client) StartDeviceFlow ¶
func (c *Client) StartDeviceFlow(ctx context.Context, clientID string, scopes []string) (DeviceAuth, error)
StartDeviceFlow requests a device + user code pair for the OAuth device flow. clientID is the public OAuth app client ID.
func (*Client) User ¶
User returns the authenticated user. It doubles as token validation: ErrUnauthorized means the token is missing, revoked, or expired.
func (*Client) WithTokenCopy ¶
WithTokenCopy returns a copy of the client using the given token. Every request-scoped call clones through here rather than mutating a shared client, which is what lets one Client template safely back every connected account: multi-account fetches never race each other's token.
type DeviceAuth ¶
type DeviceAuth struct {
DeviceCode string `json:"device_code"`
UserCode string `json:"user_code"`
VerificationURI string `json:"verification_uri"`
ExpiresIn int `json:"expires_in"`
Interval int `json:"interval"`
}
DeviceAuth is the pending device authorization the UI presents: the user opens VerificationURI and enters UserCode.
type ItemState ¶
type ItemState struct {
Author string
Number int
State string // "open", "closed", or "merged"
UpdatedAt time.Time
Found bool // false when the alias resolved null: repo gone or private, or no such number
}
ItemState is the lifecycle state of one ItemRef as of the query.
type Notification ¶
type Notification struct {
ID string `json:"id"`
Unread bool `json:"unread"`
Reason string `json:"reason"`
UpdatedAt time.Time `json:"updated_at"`
Subject NotificationSubject `json:"subject"`
Repository Repository `json:"repository"`
}
Notification is one thread from the notifications inbox.
type NotificationSubject ¶
type NotificationSubject struct {
Title string `json:"title"`
URL string `json:"url"`
Type string `json:"type"` // "Issue" | "PullRequest" | "Release" | ...
}
NotificationSubject describes what a notification thread is about.
func (NotificationSubject) Number ¶
func (s NotificationSubject) Number() int
Number parses the issue/PR number from the subject API URL. Returns 0 for subjects without one (releases, discussions).
type NotificationsResult ¶
type NotificationsResult struct {
Items []Notification
NotModified bool
Validators sourcehttp.Validators
PollInterval int
}
NotificationsResult is one notifications poll. When NotModified is true the inbox has not changed and Items is nil — the caller keeps its cached copy. Validators are echoed back on the next request, and PollInterval is the server-mandated minimum seconds between polls (X-Poll-Interval, 0 when the header is absent).
type Option ¶
type Option func(*options)
func WithAPIBase ¶
WithAPIBase overrides the REST API base URL (tests, cmd/desktop/devserver).
func WithAuthBase ¶
WithAuthBase overrides the OAuth base URL used by the device flow (tests).
func WithLogger ¶
WithLogger enables request logging at debug level.
type PullRequest ¶
type PullRequest struct {
Found bool
Number int
State string // OPEN, CLOSED, MERGED
IsDraft bool
URL string
Title string
ReviewDecision string // APPROVED, CHANGES_REQUESTED, REVIEW_REQUIRED, or empty
Checks CheckState
// Additions and Deletions are the pull request's own line counts, which are
// not the working tree's: the branch may have moved since it was opened.
Additions int
Deletions int
}
PullRequest is the branch's most recently updated pull request. Found is false when the branch has none; the caller must keep that distinct from a failed lookup, which arrives as an error instead.
type Repository ¶
type Repository struct {
FullName string `json:"full_name"`
}
Repository identifies the repository a notification belongs to.
type ReviewState ¶
type ReviewState string
ReviewState condenses GitHub's draft and review-decision fields.
const ( ReviewStateOpen ReviewState = "open" ReviewStateDraft ReviewState = "draft" ReviewStateApproved ReviewState = "approved" ReviewStateChangesRequested ReviewState = "changes_requested" ReviewStateReviewRequired ReviewState = "review_required" )
type SearchItem ¶
type SearchItem struct {
Number int
Title string
Body string
State string
URL string // html URL
Repo string // "owner/name" (repository.nameWithOwner)
Author string // author.login; "" for deleted (ghost) users
Labels []Label
IsPullRequest bool // __typename == "PullRequest"
Draft bool // isDraft; always false for issues
Review ReviewState
Checks CheckState
Additions int
Deletions int
CreatedAt time.Time
UpdatedAt time.Time
}
SearchItem is one issue or pull request from the batched GraphQL search.
type SearchRequest ¶
type SearchRequest struct {
Query string // GitHub search syntax; "sort:updated-desc" is appended by the client
Limit int // max items for this search (GraphQL `first`)
}
SearchRequest is one search in a batched GraphQL issue/PR search.