From 7e1e9eb26b21cda7a195f757e0bd3f5b4ff2266c Mon Sep 17 00:00:00 2001 From: Julien Dessaux Date: Sun, 25 May 2025 18:12:46 +0200 Subject: [PATCH] feat(client): detect pagination limit at client instantiation Closes #15 --- internal/client/client.go | 26 ++++++++++++++++---------- internal/client/repositories.go | 4 ++-- internal/client/users.go | 4 ++-- internal/provider/provider.go | 6 +++++- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/internal/client/client.go b/internal/client/client.go index 86892f0..606a78e 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -13,16 +13,15 @@ import ( ) type Client struct { - baseURI *url.URL - headers *http.Header - httpClient *http.Client + baseURI *url.URL + headers *http.Header + httpClient *http.Client + maxItemsPerPage int + maxItemsPerPageStr string } -const maxItemsPerPage = 50 -const maxItemsPerPageStr = "50" - -func NewClient(baseURL *url.URL, apiToken string) *Client { - return &Client{ +func NewClient(baseURL *url.URL, apiToken string) (*Client, error) { + c := Client{ baseURI: baseURL, headers: &http.Header{ "Accept": {"application/json"}, @@ -33,6 +32,13 @@ func NewClient(baseURL *url.URL, apiToken string) *Client { 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 { @@ -40,7 +46,7 @@ func (c *Client) sendPaginated(ctx context.Context, method string, uriRef *url.U if err != nil { return fmt.Errorf("failed to parse query string: %w", err) } - query.Set("limit", maxItemsPerPageStr) + query.Set("limit", c.maxItemsPerPageStr) page := 1 var rawResponses []json.RawMessage 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) } rawResponses = append(rawResponses, oneResponse...) - if count <= page*maxItemsPerPage { + if count <= page*c.maxItemsPerPage { break } page++ diff --git a/internal/client/repositories.go b/internal/client/repositories.go index fd2222c..dc352f8 100644 --- a/internal/client/repositories.go +++ b/internal/client/repositories.go @@ -107,7 +107,7 @@ func (c *Client) RepositoriesList(ctx context.Context) ([]Repository, error) { } uriRef := url.URL{Path: "api/v1/repos/search"} query := make(url.Values) - query.Set("limit", maxItemsPerPageStr) + query.Set("limit", c.maxItemsPerPageStr) page := 1 var repositories []Repository 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") } repositories = append(repositories, response.Data...) - if count <= page*maxItemsPerPage { + if count <= page*c.maxItemsPerPage { return repositories, nil } page++ diff --git a/internal/client/users.go b/internal/client/users.go index 25966a1..86b18f1 100644 --- a/internal/client/users.go +++ b/internal/client/users.go @@ -41,7 +41,7 @@ func (c *Client) UsersList(ctx context.Context) ([]User, error) { } uriRef := url.URL{Path: "api/v1/users/search"} query := make(url.Values) - query.Set("limit", maxItemsPerPageStr) + query.Set("limit", c.maxItemsPerPageStr) page := 1 var users []User 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") } users = append(users, response.Data...) - if count <= page*maxItemsPerPage { + if count <= page*c.maxItemsPerPage { return users, nil } page++ diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 2a360c5..c27ed6e 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -75,7 +75,11 @@ func (p *Provider) Configure(ctx context.Context, req provider.ConfigureRequest, } else { 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.ResourceData = client