fix: add getList with records wrapper + correct options format from browser capture
This commit is contained in:
@@ -21,7 +21,7 @@ func (b *BillingService) Orders(ctx context.Context) ([]provider.Order, error) {
|
||||
CreateDate string `json:"create_date"`
|
||||
}
|
||||
var raw []rainyunOrder
|
||||
if err := b.client.getWithQuery(ctx, "/expense/orders/list", map[string]string{"options": "1"}, &raw); err != nil {
|
||||
if err := b.client.getList(ctx, "/expense/orders/list", &raw); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orders := make([]provider.Order, len(raw))
|
||||
|
||||
@@ -44,6 +44,23 @@ func (c *client) getWithQuery(ctx context.Context, path string, query map[string
|
||||
return c.do(ctx, "GET", path, nil, result, query)
|
||||
}
|
||||
|
||||
// getList sends a GET request to a Rainyun list endpoint and extracts the "records" field.
|
||||
func (c *client) getList(ctx context.Context, path string, result any) error {
|
||||
var wrapper listResponse
|
||||
if err := c.do(ctx, "GET", path, nil, &wrapper, listOptions()); err != nil {
|
||||
return err
|
||||
}
|
||||
// Unmarshal the records array into the result
|
||||
recordsJSON, err := json.Marshal(wrapper.Records)
|
||||
if err != nil {
|
||||
return fmt.Errorf("marshal records: %w", err)
|
||||
}
|
||||
if err := json.Unmarshal(recordsJSON, result); err != nil {
|
||||
return fmt.Errorf("unmarshal records: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *client) post(ctx context.Context, path string, body, result any) error {
|
||||
return c.do(ctx, "POST", path, body, result, nil)
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ type rainyunDomain struct {
|
||||
|
||||
func (d *DomainService) List(ctx context.Context) ([]provider.Domain, error) {
|
||||
var raw []rainyunDomain
|
||||
if err := d.client.getWithQuery(ctx, "/product/domain/", map[string]string{"options": "1"}, &raw); err != nil {
|
||||
if err := d.client.getList(ctx, "/product/domain/", &raw); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
domains := make([]provider.Domain, len(raw))
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package rainyun
|
||||
|
||||
// listOptions returns the standard pagination query for Rainyun list endpoints.
|
||||
// Format verified via browser DevTools capture of the Rainyun web console:
|
||||
//
|
||||
// https://api.v2.rainyun.com/product/rcs/?options={url-encoded JSON}
|
||||
//
|
||||
// The decoded JSON is: {"columnFilters":{},"sort":[],"page":1,"perPage":20}
|
||||
func listOptions() map[string]string {
|
||||
return map[string]string{
|
||||
"options": `{"columnFilters":{},"sort":[],"page":1,"perPage":50}`,
|
||||
}
|
||||
}
|
||||
|
||||
// listResponse is the JSON envelope returned by Rainyun list endpoints.
|
||||
// The API wraps data in {"code":0,"data":{"records":[...],"totalRecords":N}}.
|
||||
// Our client extracts apiResp.Data ({"records":[...]}), then we unmarshal into this.
|
||||
type listResponse struct {
|
||||
Records []any `json:"records"`
|
||||
TotalRecords int `json:"totalRecords"`
|
||||
}
|
||||
@@ -29,7 +29,7 @@ type rainyunServer struct {
|
||||
|
||||
func (s *ServerService) List(ctx context.Context) ([]provider.Server, error) {
|
||||
var raw []rainyunServer
|
||||
if err := s.client.getWithQuery(ctx, "/product/rcs/", map[string]string{"options": "1"}, &raw); err != nil {
|
||||
if err := s.client.getList(ctx, "/product/rcs/", &raw); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
servers := make([]provider.Server, len(raw))
|
||||
|
||||
@@ -15,7 +15,8 @@ func TestServerList(t *testing.T) {
|
||||
}
|
||||
resp := map[string]any{
|
||||
"code": 0,
|
||||
"data": []map[string]any{
|
||||
"data": map[string]any{
|
||||
"records": []map[string]any{
|
||||
{
|
||||
"id": 12001,
|
||||
"name": "web-server",
|
||||
@@ -28,6 +29,8 @@ func TestServerList(t *testing.T) {
|
||||
"expire_date": "2026-08-15",
|
||||
},
|
||||
},
|
||||
"totalRecords": 1,
|
||||
},
|
||||
}
|
||||
json.NewEncoder(w).Encode(resp)
|
||||
}))
|
||||
|
||||
@@ -17,7 +17,7 @@ func (s *StorageService) List(ctx context.Context) ([]provider.StorageInstance,
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
if err := s.client.getWithQuery(ctx, "/product/ros/instance", map[string]string{"options": "1"}, &raw); err != nil {
|
||||
if err := s.client.getList(ctx, "/product/ros/instance", &raw); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
instances := make([]provider.StorageInstance, len(raw))
|
||||
|
||||
Reference in New Issue
Block a user