package pocketbase import ( "context" "encoding/json" "fmt" "net/http" "net/url" "time" ) // Client handles interactions with the PocketBase API. type Client struct { endpoint *url.URL http *http.Client } // New creates a new PocketBase client. func New(endpoint string) *Client { u, err := url.Parse(endpoint) if err != nil || u == nil { return &Client{ endpoint: &url.URL{}, http: &http.Client{Timeout: 30 * time.Second}, } } return &Client{ endpoint: u, http: &http.Client{ Timeout: 30 * time.Second, }, } } type record struct { URL string `json:"url"` } type recordsResponse struct { Items []record `json:"items"` } // GetBookmarkURLs retrieves URLs from the collection. func (c *Client) GetBookmarkURLs(ctx context.Context) ([]string, error) { // Clone the endpoint URL to avoid mutation on repeated calls. u := *c.endpoint q := u.Query() q.Set("perPage", "200") q.Set("fields", "url") u.RawQuery = q.Encode() req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil) if err != nil { return nil, fmt.Errorf("creating request: %w", err) } resp, err := c.http.Do(req) if err != nil { return nil, err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("unexpected status: %d", resp.StatusCode) } var recs recordsResponse if err := json.NewDecoder(resp.Body).Decode(&recs); err != nil { return nil, err } var urls []string for _, r := range recs.Items { if r.URL != "" { urls = append(urls, r.URL) } } return urls, nil }