Documentation
¶
Overview ¶
Package jsonapi is the one transport every Truestamp JSON:API client shares: the authenticated request carrying the tenant header, the response size cap, and the classification of the error envelope into a small set of sentinels a command can errors.Is. The resource packages (internal/beacons, internal/blocks, internal/teams, internal/items, internal/proof) own only their routes and their decoding; each used to carry its own copy of this file, and the copies had started to differ in which statuses mapped to which class.
Index ¶
- Constants
- Variables
- func Do(ctx context.Context, cfg Config, method, path string, body []byte) ([]byte, error)
- func DoRaw(ctx context.Context, cfg Config, method, path string, body []byte) (*http.Response, []byte, error)
- func Get(ctx context.Context, cfg Config, path string) ([]byte, error)
- func Post(ctx context.Context, cfg Config, path string, payload any) ([]byte, error)
- func SetPageQuery(q url.Values, limit int, after, before string, count bool)
- func SortByID(oldestFirst bool) string
- type APIError
- type Config
- type PageInfo
Constants ¶
const CodeInvalidKeyset = "invalid_keyset"
CodeInvalidKeyset is the server's code for a page[after] / page[before] value that is not a cursor it issued.
Variables ¶
var ( ErrForbidden = errors.New("forbidden") ErrNotFound = errors.New("not found") ErrBadRequest = errors.New("bad request") ErrRateLimited = errors.New("rate limited") ErrServer = errors.New("server error") )
Class sentinels. An *APIError wraps exactly one of them, so a caller can errors.Is the class while still showing the server's detail text.
Functions ¶
func Do ¶
Do issues an authenticated request and returns the body on 2xx. Any other status is an *APIError wrapping its class sentinel, with the Retry-After header preserved on 429.
func DoRaw ¶
func DoRaw(ctx context.Context, cfg Config, method, path string, body []byte) (*http.Response, []byte, error)
DoRaw is Do without the status classification: the response (its body already read, capped and closed) comes back for a client with its own error envelope to parse, which proof generation's `meta.code` needs. A missing credential is still an *APIError, because no request is sent.
func SetPageQuery ¶
SetPageQuery writes the page parameters every keyset-paged list shares: page[limit] for the page size, page[after] or page[before] to continue from a cursor in either direction, and page[count]=true when the caller wants the server's total. Sort is the caller's, and must be re-sent on every page: this client rebuilds the query rather than following the server's links, so nothing carries over.
Types ¶
type APIError ¶
type APIError struct {
Status int
Code string // errors[].code, the server's machine-readable reason, when present
Pointer string // errors[].source.pointer, when present
Detail string
RetryAfter string // verbatim Retry-After header on 429
// Sentinel is the class this error belongs to; Unwrap returns it. A
// resource package may narrow it to one of its own domain sentinels
// once it has read the structural discriminators, as teams does for
// the plan-limit and entitlement rejections on create.
Sentinel error
}
APIError carries the HTTP status and the preserved `errors[].detail` (falling back to `title`) from the JSON:API error envelope.
func NotFound ¶
NotFound is the error a client returns when a filter-style lookup came back empty and there was no 404 to classify.
func ParseError ¶
ParseError classifies a non-2xx response. It keeps `errors[].detail` (or `title`) and the `source.pointer` of the first error that carries one: the server can return several errors at once (a free-plan user requesting team_retains trips both the plan-limit and the entitlement rejection), and the pointer is the structural discriminator, so it wins over array position.
type Config ¶
type Config struct {
APIURL string // e.g. https://www.truestamp.com/api/json
Team string // optional tenant id; sent verbatim as the `tenant` header
}
Config carries what a request needs beyond the credential, which the process-wide auth.Authorizer installed in cmd/root supplies out of band.
type PageInfo ¶
type PageInfo struct {
// NextCursor is the page[after] value lifted from links.next; empty on
// the last page. An unparseable link also reads as empty, which is the
// safe reading: a bad cursor would otherwise loop.
NextCursor string
// PrevCursor is the page[before] value lifted from links.prev; empty on
// the first page.
PrevCursor string
// Total is meta.page.total, present only when the request asked for
// page[count]=true; zero otherwise.
Total int
// Limit is meta.page.limit, the page size the server actually used.
// Every collection clamps page[limit] to its max_page_size (250 by
// default) rather than refusing it, so this can be smaller than what
// was asked for; zero when the server did not report one.
Limit int
}
PageInfo is what a list response says about the pages around it.