Documentation
¶
Overview ¶
Package cloudflare is a small client for the parts of the Cloudflare v4 REST API that `flue relay setup` needs: verifying a user's API token, listing the accounts it can reach, and deploying the relay Worker — script, Durable Object, static assets and all — into the account they choose.
It is deliberately not a general Cloudflare SDK. Every endpoint here exists because one step of the setup flow needs it, and the request shapes are pinned by fixtures in client_test.go rather than inferred, because the parts of this API that matter most (the asset upload session, the multipart script metadata) are the parts the published documentation describes least precisely. Where the docs and Cloudflare's own clients disagreed, the fixtures follow the clients — see the notes on hashOf and on migrations.
The API token is a field on Client and is never logged: it goes into an Authorization header and nowhere else. Client.String redacts it so that a stray %v cannot undo that.
Index ¶
- type APIError
- type Account
- type Asset
- type Client
- func (c *Client) Accounts(ctx context.Context) ([]Account, error)
- func (c *Client) Deploy(ctx context.Context, in DeployInput) error
- func (c *Client) EnableSubdomain(ctx context.Context, accountID, script string) (string, error)
- func (c Client) GoString() string
- func (c *Client) SetSecret(ctx context.Context, accountID, script, name, value string) error
- func (c Client) String() string
- func (c *Client) VerifyToken(ctx context.Context) error
- type DeployInput
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type APIError ¶
APIError is a failure Cloudflare reported inside its own envelope, as opposed to a transport failure. It carries the first error's code and message, which are what the setup flow shows the user.
type Client ¶
type Client struct {
HTTP *http.Client
Token string
Base string // default https://api.cloudflare.com/client/v4
}
Client talks to the Cloudflare v4 REST API with a user-supplied token. The zero value is usable and targets the real API.
func (*Client) Accounts ¶
Accounts lists the accounts the token can act on, so setup can ask which one the relay should live in. It follows pagination to the last page.
func (*Client) Deploy ¶
func (c *Client) Deploy(ctx context.Context, in DeployInput) error
Deploy uploads the assets, then PUTs the script with its metadata.
The order is forced: the script's metadata has to name a completion token that only the finished asset upload can produce.
func (*Client) EnableSubdomain ¶
EnableSubdomain makes the script reachable on workers.dev and returns the full host, e.g. "flue-relay.<sub>.workers.dev".
func (*Client) SetSecret ¶
SetSecret sets a secret on the script. Cloudflare stores it as a `secret_text` binding, so the Worker reads it off env like any other binding but the value is never readable back.
func (Client) String ¶
String redacts the token. Client is carried through the setup flow next to things that do get logged, and the token must never be one of them.
The receiver is a value, not a pointer, because a pointer receiver would leave `%v` on a Client value printing the token verbatim — and a Client is small enough to be passed around by value. GoString covers `%#v`, which ignores Stringer entirely and would otherwise dump every field.
type DeployInput ¶
type DeployInput struct {
AccountID string
ScriptName string // "flue-relay"
Module []byte // the built worker, ESM
CompatibilityDate string // "2026-08-01"
// NewSQLiteClasses names Durable Object classes being introduced. It is
// set on the first deploy and empty afterwards; Deploy also recovers on its
// own when Cloudflare says the migration is already applied.
//
// These must be *SQLite* classes: the free plan offers no other storage
// backend for Durable Objects, so a key-value migration would shut free
// accounts out of the relay entirely.
NewSQLiteClasses []string
DOBindings map[string]string // name -> class: {"HUB": "DaemonHub"}
Assets []Asset
AssetsRunWorkerFirst []string // ["/daemon", "/client", "/api/*"]
// PlainTextVars become bindings of type "plain_text": ordinary,
// non-secret env vars the Worker can read. The relay's version stamp
// travels this way. Values here are visible to anyone who can read the
// script in the dashboard — nothing secret may ever ride one.
PlainTextVars map[string]string
// AssetHeaders is a `_headers` document — response headers for the static
// assets, in the file format Cloudflare's asset router parses. Empty sends
// no header config at all. See assetsConfig.Headers for why this travels in
// the script metadata rather than as a file among the assets.
//
// It applies to responses the asset router produces, including the ones a
// Worker asks for through its assets binding, and not to responses the
// Worker constructs itself.
AssetHeaders string
// AssetsBinding is the name the Worker reads its static assets off env
// under — "ASSETS" for the relay, matching `assets.binding` in
// relay/wrangler.jsonc. It is emitted as a binding of type "assets".
//
// This is separate from attaching the assets at all, and the distinction is
// easy to get wrong: the completion token in metadata.assets.jwt makes
// Cloudflare's *router* serve the files, and that alone is enough for a
// Worker that only ever needs static paths served for it. It does not
// create env.<name>. A Worker that calls env.ASSETS.fetch(...) itself — as
// the relay does, to fall through to the SPA on unmatched /api/* — needs
// this binding too, or that call is on undefined at runtime.
//
// Empty means no binding, which is correct for a router-only deploy.
AssetsBinding string
// Observability turns on Workers Logs for the script, matching
// `"observability": {"enabled": true}` in relay/wrangler.jsonc. Without it
// a relay deployed by `flue relay setup` would have no logs to debug from
// where a wrangler-deployed one would.
Observability bool
}
DeployInput is everything one deploy of the relay Worker needs.