84 lines
2.3 KiB
Go
84 lines
2.3 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
)
|
|
|
|
type listOpts struct {
|
|
jsonMode bool
|
|
page int
|
|
limit int
|
|
}
|
|
|
|
func parseListFlags(name string, args []string) (*listOpts, []string, error) {
|
|
fs := flag.NewFlagSet(name, flag.ExitOnError)
|
|
o := &listOpts{}
|
|
fs.BoolVar(&o.jsonMode, "json", false, "emit raw API JSON")
|
|
fs.IntVar(&o.page, "page", 0, "fetch a single page (no auto-pagination)")
|
|
fs.IntVar(&o.limit, "limit", 0, "items per page (100-1000)")
|
|
if err := fs.Parse(args); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
if err := validateLimit(o.limit); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
return o, fs.Args(), nil
|
|
}
|
|
|
|
// fetchList fetches one or all pages of a list endpoint.
|
|
// On single-page (`--page` set), singleRaw holds the unmodified body
|
|
// so --json can echo it byte-for-byte.
|
|
func (c *Client) fetchList(base string, o *listOpts) (items []json.RawMessage, p Paginator, singleRaw []byte, err error) {
|
|
if o.page > 0 {
|
|
err = c.listPaged(base, o.page, o.limit, nil, &singleRaw)
|
|
if err != nil {
|
|
return
|
|
}
|
|
items, p, err = decodeListPage(singleRaw)
|
|
return
|
|
}
|
|
items, p, err = c.listAll(base, o.limit, decodeListPage)
|
|
return
|
|
}
|
|
|
|
func decodeListPage(raw []byte) ([]json.RawMessage, Paginator, error) {
|
|
var resp struct {
|
|
Data []json.RawMessage `json:"data"`
|
|
Paginator Paginator `json:"paginator"`
|
|
}
|
|
if err := json.Unmarshal(raw, &resp); err != nil {
|
|
return nil, Paginator{}, err
|
|
}
|
|
return resp.Data, resp.Paginator, nil
|
|
}
|
|
|
|
// emitList prints either raw JSON (single-page or merged) or invokes
|
|
// the table renderer over decoded rows.
|
|
func emitList(items []json.RawMessage, p Paginator, singleRaw []byte, o *listOpts, table func([]json.RawMessage) error) error {
|
|
if o.jsonMode {
|
|
if singleRaw != nil {
|
|
return printJSON(singleRaw)
|
|
}
|
|
return printMergedJSON(items, p)
|
|
}
|
|
return table(items)
|
|
}
|
|
|
|
// parseGetFlags parses `get` subcommand flags and requires a single ID arg.
|
|
func parseGetFlags(name string, args []string) (jsonMode bool, id string, err error) {
|
|
fs := flag.NewFlagSet(name, flag.ExitOnError)
|
|
fs.BoolVar(&jsonMode, "json", false, "emit raw API JSON")
|
|
if e := fs.Parse(args); e != nil {
|
|
err = e
|
|
return
|
|
}
|
|
rest := fs.Args()
|
|
if len(rest) != 1 {
|
|
err = fmt.Errorf("%s: expected exactly one ID argument", name)
|
|
return
|
|
}
|
|
id = rest[0]
|
|
return
|
|
}
|