feat(client): detect pagination limit at client instantiation

Closes #15
This commit is contained in:
Julien Dessaux 2025-05-25 18:12:46 +02:00
parent f4d69460af
commit 7e1e9eb26b
Signed by: adyxax
GPG key ID: F92E51B86E07177E
4 changed files with 25 additions and 15 deletions

View file

@ -13,16 +13,15 @@ import (
) )
type Client struct { type Client struct {
baseURI *url.URL baseURI *url.URL
headers *http.Header headers *http.Header
httpClient *http.Client httpClient *http.Client
maxItemsPerPage int
maxItemsPerPageStr string
} }
const maxItemsPerPage = 50 func NewClient(baseURL *url.URL, apiToken string) (*Client, error) {
const maxItemsPerPageStr = "50" c := Client{
func NewClient(baseURL *url.URL, apiToken string) *Client {
return &Client{
baseURI: baseURL, baseURI: baseURL,
headers: &http.Header{ headers: &http.Header{
"Accept": {"application/json"}, "Accept": {"application/json"},
@ -33,6 +32,13 @@ func NewClient(baseURL *url.URL, apiToken string) *Client {
Timeout: time.Minute, Timeout: time.Minute,
}, },
} }
settings, err := c.settingsApiGet()
if err != nil {
return nil, fmt.Errorf("failed to get settings api: %w", err)
}
c.maxItemsPerPage = settings.MaxResponseItems
c.maxItemsPerPageStr = strconv.Itoa(c.maxItemsPerPage)
return &c, nil
} }
func (c *Client) sendPaginated(ctx context.Context, method string, uriRef *url.URL, payload any, response any) error { func (c *Client) sendPaginated(ctx context.Context, method string, uriRef *url.URL, payload any, response any) error {
@ -40,7 +46,7 @@ func (c *Client) sendPaginated(ctx context.Context, method string, uriRef *url.U
if err != nil { if err != nil {
return fmt.Errorf("failed to parse query string: %w", err) return fmt.Errorf("failed to parse query string: %w", err)
} }
query.Set("limit", maxItemsPerPageStr) query.Set("limit", c.maxItemsPerPageStr)
page := 1 page := 1
var rawResponses []json.RawMessage var rawResponses []json.RawMessage
for { for {
@ -56,7 +62,7 @@ func (c *Client) sendPaginated(ctx context.Context, method string, uriRef *url.U
return fmt.Errorf("failed to unmarshal message: %w", err) return fmt.Errorf("failed to unmarshal message: %w", err)
} }
rawResponses = append(rawResponses, oneResponse...) rawResponses = append(rawResponses, oneResponse...)
if count <= page*maxItemsPerPage { if count <= page*c.maxItemsPerPage {
break break
} }
page++ page++

View file

@ -107,7 +107,7 @@ func (c *Client) RepositoriesList(ctx context.Context) ([]Repository, error) {
} }
uriRef := url.URL{Path: "api/v1/repos/search"} uriRef := url.URL{Path: "api/v1/repos/search"}
query := make(url.Values) query := make(url.Values)
query.Set("limit", maxItemsPerPageStr) query.Set("limit", c.maxItemsPerPageStr)
page := 1 page := 1
var repositories []Repository var repositories []Repository
var response Response var response Response
@ -122,7 +122,7 @@ func (c *Client) RepositoriesList(ctx context.Context) ([]Repository, error) {
return nil, fmt.Errorf("got a non OK status when searching repositories") return nil, fmt.Errorf("got a non OK status when searching repositories")
} }
repositories = append(repositories, response.Data...) repositories = append(repositories, response.Data...)
if count <= page*maxItemsPerPage { if count <= page*c.maxItemsPerPage {
return repositories, nil return repositories, nil
} }
page++ page++

View file

@ -41,7 +41,7 @@ func (c *Client) UsersList(ctx context.Context) ([]User, error) {
} }
uriRef := url.URL{Path: "api/v1/users/search"} uriRef := url.URL{Path: "api/v1/users/search"}
query := make(url.Values) query := make(url.Values)
query.Set("limit", maxItemsPerPageStr) query.Set("limit", c.maxItemsPerPageStr)
page := 1 page := 1
var users []User var users []User
var response Response var response Response
@ -56,7 +56,7 @@ func (c *Client) UsersList(ctx context.Context) ([]User, error) {
return nil, fmt.Errorf("got a non OK status when searching users") return nil, fmt.Errorf("got a non OK status when searching users")
} }
users = append(users, response.Data...) users = append(users, response.Data...)
if count <= page*maxItemsPerPage { if count <= page*c.maxItemsPerPage {
return users, nil return users, nil
} }
page++ page++

View file

@ -75,7 +75,11 @@ func (p *Provider) Configure(ctx context.Context, req provider.ConfigureRequest,
} else { } else {
apiToken = data.ApiToken.ValueString() apiToken = data.ApiToken.ValueString()
} }
client := client.NewClient(baseURI, apiToken) client, err := client.NewClient(baseURI, apiToken)
if err != nil {
resp.Diagnostics.AddError("failed to instantiate forgejo client", err.Error())
return
}
resp.DataSourceData = client resp.DataSourceData = client
resp.ResourceData = client resp.ResourceData = client