Documentation
¶
Overview ¶
Package confluence is a thin REST client for Confluence Cloud: enough of the API to fill the page mirror, plus the user-initiated page writes that go through the origin (create / update). It never writes to gadak's SQLite mirror — after a write, callers re-read from the origin (and, on a later surface, SyncPage the same way SyncIssue follows a Jira write).
The token lives only in the Authorization header. It is never put in an error, a log line or a URL (constitution article 8).
Index ¶
- Variables
- type APIError
- type BodyADF
- type Client
- func (c *Client) AddPageComment(ctx context.Context, pageID, adf string) (Comment, error)
- func (c *Client) BaseURL() string
- func (c *Client) Comments(ctx context.Context, pageID string) ([]Comment, error)
- func (c *Client) CreatePage(ctx context.Context, spaceKey, title, adf string, parentID string) (Page, error)
- func (c *Client) Page(ctx context.Context, id string) (Page, error)
- func (c *Client) PageVersions(ctx context.Context, id string) ([]Version, error)
- func (c *Client) Raw(ctx context.Context, method, path string, body []byte, mutating bool) (status int, out []byte, err error)
- func (c *Client) SearchPages(ctx context.Context, cql string, fn func([]Page) error) error
- func (c *Client) SiteURL() string
- func (c *Client) Space(ctx context.Context, key string) (Space, error)
- func (c *Client) Spaces(ctx context.Context) ([]Space, error)
- func (c *Client) TakeUsage() Usage
- func (c *Client) UpdatePage(ctx context.Context, id, title, adf string, nextVersion int) (Page, error)
- func (c *Client) Usage() Usage
- type Comment
- type ContentBody
- type Label
- type LabelsPage
- type Page
- type PageMetadata
- type Space
- type SpaceRef
- type Usage
- type User
- type Version
Constants ¶
This section is empty.
Variables ¶
var ErrAuth = atlhttp.Auth("confluence")
ErrAuth is the Confluence-named rejected credential. It unwraps to atlhttp.ErrAuth so Watch detects it without a per-source branch. Error() keeps the "confluence:" prefix so last_error names the source. Callers keep using errors.Is(err, confluence.ErrAuth).
var ErrConflict = &APIError{Status: http.StatusConflict}
ErrConflict is a 409. On update, that is a stale version.number: the caller refetches and decides. This client does not retry a 409.
var ErrNotFound = errors.New("confluence: content not found")
ErrNotFound marks a 404 on a specific content id. A page can vanish (or get view-restricted) between the CQL listing and the per-page fetch on a busy site; callers skip that page instead of aborting the run.
Functions ¶
This section is empty.
Types ¶
type APIError ¶ added in v0.16.0
APIError is a non-2xx Confluence answer with its HTTP status. Callers distinguish a stale version (409) from other rejections with Status or errors.Is(err, ErrConflict) — not by matching a human-readable substring. The shape follows jira.APIError.
type Client ¶
type Client struct {
HTTP *http.Client
// Retries is the total number of attempts per request; Backoff is the first
// wait, doubling per attempt and capped at 30 s.
Retries int
Backoff time.Duration
// PauseBetween is slept after each Page fetch (rate politeness). Zero in tests.
PauseBetween time.Duration
// contains filtered or unexported fields
}
Client talks to Confluence Cloud under <site>/wiki.
func (*Client) AddPageComment ¶ added in v0.16.1
AddPageComment POSTs a top-level comment on a page (v1 content with type=comment and the page as container). ADF is the atlas_doc_format value as a JSON string, same as CreatePage.
func (*Client) Comments ¶
Comments returns every comment on a page plus one level of replies (start/limit paging on each parent).
func (*Client) CreatePage ¶ added in v0.16.0
func (c *Client) CreatePage(ctx context.Context, spaceKey, title, adf string, parentID string) (Page, error)
CreatePage POSTs a page to the origin. ADF is the atlas_doc_format value as a JSON string (the same representation the read path already handles). parentID, when non-empty, is sent as ancestors[0].id.
The returned page is a GET of the new id, not the request body and not the POST envelope — the origin is the record.
func (*Client) Page ¶
Page fetches one content id with ADF body, version, space, ancestors, and labels. metadata.labels is the first page only (≤25 results); see LabelNames.
func (*Client) PageVersions ¶ added in v0.16.0
PageVersions lists every history stamp for a content id (GET /content/{id}/version). Bodies are not requested. Pagination follows _links.next the same way SearchPages does. The server's order is not trusted: results are sorted by Number ascending before return.
func (*Client) Raw ¶
func (c *Client) Raw(ctx context.Context, method, path string, body []byte, mutating bool) (status int, out []byte, err error)
Raw sends a request and returns the HTTP status and response body without JSON decoding. Path is relative to the wiki origin (e.g. /rest/api/… or /api/v2/… — not the /wiki prefix). Absolute URLs are rejected. mutating selects the write retry policy (429/503 only).
A completed HTTP response always returns err == nil with the status and body (including non-2xx). err is reserved for transport failures and bad paths.
func (*Client) SearchPages ¶
SearchPages runs a CQL search with expand=version,space and follows _links.next. fn is called once per page of results (may be empty only on the final empty page).
func (*Client) Space ¶
Space fetches one space by key with expand=homepage. 404 wraps ErrNotFound (same as Page); callers that tolerate a missing/restricted space skip it.
func (*Client) Spaces ¶
Spaces lists every space the credential can see (start/limit paging). expand=homepage fills Space.Homepage so callers can store the root page id.
func (*Client) TakeUsage ¶
TakeUsage returns the current counters and zeroes the numeric fields so a flusher can accumulate into daily totals without double-counting.
LastThrottledAt is a timestamp, not a counter: it is included in the snapshot but is NOT cleared.
func (*Client) UpdatePage ¶ added in v0.16.0
func (c *Client) UpdatePage(ctx context.Context, id, title, adf string, nextVersion int) (Page, error)
UpdatePage PUTs a page. nextVersion must be the origin's current version.number + 1. A stale number is a 409 / ErrConflict — the caller refetches and decides; this method does not retry.
The returned page is a GET after the write, same as CreatePage.
type Comment ¶
type Comment struct {
ID string `json:"id"`
Title string `json:"title"`
Body ContentBody `json:"body"`
Version Version `json:"version"`
}
Comment is a child comment (or reply) on a page.
type ContentBody ¶
type ContentBody struct {
AtlasDocFormat *BodyADF `json:"atlas_doc_format"`
}
ContentBody is the expand=body.atlas_doc_format payload.
func (ContentBody) ADFRaw ¶
func (b ContentBody) ADFRaw() json.RawMessage
ADFRaw returns the atlas_doc_format value as json.RawMessage for storage/FTS. Value is a JSON string of the ADF document.
type LabelsPage ¶
type LabelsPage struct {
Results []Label `json:"results"`
Size int `json:"size"`
Limit int `json:"limit"`
Start int `json:"start"`
}
LabelsPage is the expanded metadata.labels object. expand=metadata.labels returns only the first page (default limit 25). Real wiki pages almost always have single-digit labels, so paging is intentionally not followed.
type Page ¶
type Page struct {
ID string `json:"id"`
Type string `json:"type"`
Status string `json:"status"`
Title string `json:"title"`
Space SpaceRef `json:"space"`
Version Version `json:"version"`
Body ContentBody `json:"body"`
// Metadata is present when expand includes metadata.labels (full Page fetch).
Metadata PageMetadata `json:"metadata"`
// Ancestors, when expanded, lists the parent chain; the last entry is the direct parent.
Ancestors []struct {
ID string `json:"id"`
} `json:"ancestors"`
Links struct {
WebUI string `json:"webui"`
} `json:"_links"`
}
Page is a content row (search hit or full fetch).
func (Page) LabelNames ¶
LabelNames returns label names from metadata.labels.results in API order. Always returns a non-nil empty slice when none are present. Does not sort — callers that need determinism (sync → store) sort themselves.
Limit: expand=metadata.labels only includes the first results page (≤25). Pages with more labels than that will be truncated; paging is not followed because production pages typically have single-digit labels.
type PageMetadata ¶
type PageMetadata struct {
Labels LabelsPage `json:"labels"`
}
PageMetadata is the expand=metadata.* payload on a content row.
type Space ¶
type Space struct {
Key string `json:"key"`
Name string `json:"name"`
Type string `json:"type"`
Homepage *struct {
ID string `json:"id"`
} `json:"homepage"`
}
Space is one space listing row. Homepage is present when expand=homepage was requested; its id is the content id of the space's root page (same id scheme as Page.ID / pages.parent_id).
type Usage ¶
Usage is a point-in-time snapshot of this client's outbound Confluence traffic. Counters are process-local until a caller persists them (see store.api_usage).
Requests counts every HTTP attempt, including retries: that is the unit that draws from Confluence's rate budget.
type Version ¶
type Version struct {
Number int `json:"number"`
When string `json:"when"`
Message string `json:"message"`
MinorEdit bool `json:"minorEdit"`
By User `json:"by"`
}
Version is the content version stamp. Message and MinorEdit are filled on GET /content/{id}/version rows; the expand=version object on a Page fetch typically omits them.