Liking cljdoc? Tell your friends :D

com.heavycomputation.cloudflare

Heavy Computation's Cloudflare toolkit for Clojure.

A thin, batteries-included wrapper over the Cloudflare products we reach for in every webapp. Features are added incrementally:

  • R2 object storage (S3-compatible) -> com.heavycomputation.cloudflare.r2
  • Images upload/manage/serve -> com.heavycomputation.cloudflare.images

This namespace re-exports R2's high-level API for convenience. Images is not flattened in here: its CRUD verbs (get/list/update/delete/exists?/ get-bytes/request …) would collide with R2's, and a bare upload/delete at the top level couldn't tell which product you meant. So Images is used through its own namespace — (require '[…cloudflare.images :as images]) — and so is R2's raw escape hatch. For the full surface, use the per-product namespaces directly.

get/list shadow clojure.core names and are excluded here; refer to them qualified (e.g. cloudflare/get).

Heavy Computation's Cloudflare toolkit for Clojure.

A thin, batteries-included wrapper over the Cloudflare products we reach for
in every webapp. Features are added incrementally:

  - R2     object storage  (S3-compatible)   -> com.heavycomputation.cloudflare.r2
  - Images upload/manage/serve                -> com.heavycomputation.cloudflare.images

This namespace re-exports R2's high-level API for convenience. Images is *not*
flattened in here: its CRUD verbs (`get`/`list`/`update`/`delete`/`exists?`/
`get-bytes`/`request` …) would collide with R2's, and a bare `upload`/`delete`
at the top level couldn't tell which product you meant. So Images is used
through its own namespace — `(require '[…cloudflare.images :as images])` — and
so is R2's raw escape hatch. For the full surface, use the per-product
namespaces directly.

`get`/`list` shadow `clojure.core` names and are excluded here; refer to them
qualified (e.g. `cloudflare/get`).
raw docstring

com.heavycomputation.cloudflare.images

Cloudflare Images: store, manage, and serve images.

Unlike R2 (which speaks S3 and is signed with SigV4), Images has two distinct surfaces, and this namespace covers both:

  • the management API — Cloudflare's REST API v4, authenticated with a Bearer token (see internal.api) — for uploading, listing, updating and deleting images; and
  • delivery — images are served from imagedelivery.net/<hash>/<id>/ <variant>, a URL this namespace builds (and, for private images, signs) with no network round-trip.

The public API:

(client m) ; build a client handle (upload client body) ; upload a File/byte[]/InputStream (upload-url client url) ; ingest a remote image by URL (direct-upload-url client) ; a one-time URL the browser uploads to (get client id) ; fetch details; also head-less exists? (list client) / (list-seq …) ; enumerate images (v2 cursor pagination) (update client id m) ; edit metadata / requireSignedURLs (delete client id) ; remove an image (idempotent) (get-bytes client id) ; original bytes; also get-stream (stats client) ; usage counts (signing-keys client) ; the URL-signing keys (delivery-url client id v) ; build (optionally signed) a delivery URL (request client req) ; escape hatch to the raw v4 API

get/list/update shadow clojure.core names, so this namespace excludes them; refer to them qualified (e.g. images/get).

Cloudflare Images: store, manage, and serve images.

Unlike R2 (which speaks S3 and is signed with SigV4), Images has two distinct
surfaces, and this namespace covers both:

  - the **management API** — Cloudflare's REST API v4, authenticated with a
    Bearer token (see `internal.api`) — for uploading, listing, updating and
    deleting images; and
  - **delivery** — images are *served* from `imagedelivery.net/<hash>/<id>/
    <variant>`, a URL this namespace builds (and, for private images, signs)
    with no network round-trip.

The public API:

  (client m)                     ; build a client handle
  (upload client body)           ; upload a File/byte[]/InputStream
  (upload-url client url)        ; ingest a remote image by URL
  (direct-upload-url client)     ; a one-time URL the browser uploads to
  (get client id)                ; fetch details; also head-less exists?
  (list client) / (list-seq …)   ; enumerate images (v2 cursor pagination)
  (update client id m)           ; edit metadata / requireSignedURLs
  (delete client id)             ; remove an image (idempotent)
  (get-bytes client id)          ; original bytes; also get-stream
  (stats client)                 ; usage counts
  (signing-keys client)          ; the URL-signing keys
  (delivery-url client id v)     ; build (optionally signed) a delivery URL
  (request client req)           ; escape hatch to the raw v4 API

`get`/`list`/`update` shadow `clojure.core` names, so this namespace excludes
them; refer to them qualified (e.g. `images/get`).
raw docstring

com.heavycomputation.cloudflare.internal.api

A tiny, zero-dependency client for the Cloudflare REST API v4: attaches a Bearer token and sends requests over the JDK's java.net.http client. It is the transport the Images product needs — the counterpart to internal.s3, but for Cloudflare's own JSON API rather than S3.

It handles two request-body shapes, both hand-rolled so nothing is pulled in: a JSON body (:json <clj-data>) and a multipart/form-data upload (:multipart [part …]). It is stateless and carries no per-product knowledge; callers build paths and interpret responses.

A tiny, zero-dependency client for the Cloudflare REST API v4: attaches a
Bearer token and sends requests over the JDK's `java.net.http` client. It is
the transport the Images product needs — the counterpart to `internal.s3`,
but for Cloudflare's own JSON API rather than S3.

It handles two request-body shapes, both hand-rolled so nothing is pulled in:
a JSON body (`:json <clj-data>`) and a `multipart/form-data` upload
(`:multipart [part …]`). It is stateless and carries no per-product knowledge;
callers build paths and interpret responses.
raw docstring

com.heavycomputation.cloudflare.internal.json

Just enough JSON to talk to the Cloudflare REST API v4: read the small {success, errors, messages, result} envelopes it returns and write the compact request bodies (and x-amz-free metadata blobs) we send.

This is deliberately not a general JSON library — but it is a correct one for the subset it covers: objects, arrays, strings (with \uXXXX and the usual escapes), numbers (long or double), true/false/null. Keeping it in-house preserves the library's zero-dependency promise, the same way internal.xml does for S3.

read returns objects as maps with string keys (Cloudflare's are camelCase, so callers destructure with :strs); write accepts maps with string or keyword keys.

Just enough JSON to talk to the Cloudflare REST API v4: read the small
`{success, errors, messages, result}` envelopes it returns and write the
compact request bodies (and `x-amz`-free metadata blobs) we send.

This is deliberately *not* a general JSON library — but it is a correct one
for the subset it covers: objects, arrays, strings (with `\uXXXX` and the
usual escapes), numbers (long or double), `true`/`false`/`null`. Keeping it
in-house preserves the library's zero-dependency promise, the same way
`internal.xml` does for S3.

`read` returns objects as maps with *string* keys (Cloudflare's are camelCase,
so callers destructure with `:strs`); `write` accepts maps with string or
keyword keys.
raw docstring

com.heavycomputation.cloudflare.internal.s3

A tiny, zero-dependency S3 client: signs each request with SigV4 and sends it over the JDK's java.net.http client. It is path-style and stateless — just the transport R2 needs, with no per-operation knowledge baked in.

A tiny, zero-dependency S3 client: signs each request with SigV4 and sends it
over the JDK's `java.net.http` client. It is path-style and stateless — just
the transport R2 needs, with no per-operation knowledge baked in.
raw docstring

com.heavycomputation.cloudflare.internal.sigv4

AWS Signature Version 4 signing, pared down to what R2 needs.

Header-based authorization (not presigned query strings), SHA-256 payload hashing, path-style URLs. No chunked/streaming signature. The crypto is all JDK-native (java.security, javax.crypto), so this carries no dependency.

sign is pure — timestamps are passed in rather than read from the clock — which lets it be checked against AWS's published test vectors.

AWS Signature Version 4 signing, pared down to what R2 needs.

Header-based authorization (not presigned query strings), SHA-256 payload
hashing, path-style URLs. No chunked/streaming signature. The crypto is all
JDK-native (`java.security`, `javax.crypto`), so this carries no dependency.

`sign` is pure — timestamps are passed in rather than read from the clock —
which lets it be checked against AWS's published test vectors.
raw docstring

com.heavycomputation.cloudflare.internal.xml

Just enough XML to talk to S3: pull a tag's text out of a small response document and build the CompleteMultipartUpload request body.

This is deliberately not a general XML library. The documents S3 returns for the handful of operations we use are small, flat, and machine-generated, so a tag scan is enough and avoids a parser dependency.

Just enough XML to talk to S3: pull a tag's text out of a small response
document and build the CompleteMultipartUpload request body.

This is deliberately *not* a general XML library. The documents S3 returns
for the handful of operations we use are small, flat, and machine-generated,
so a tag scan is enough and avoids a parser dependency.
raw docstring

com.heavycomputation.cloudflare.r2

Cloudflare R2 object storage.

R2 speaks the S3 API, so this namespace signs requests with AWS Signature V4 and sends them over the JDK's http client (see the internal namespaces) — no AWS SDK, no dependencies. The public API:

(bucket m) ; build a bucket handle (put bucket key body) ; upload an object, multipart automatically (get-bytes bucket key) ; download; also head/exists?/get/get-stream (delete bucket key) ; remove; also delete-many for batches (list bucket opts) ; enumerate by prefix; also list-seq (lazy) (presigned-url bucket k) ; time-limited download/upload URL (create-multipart-upload bucket k) ; broker a browser-direct multipart upload (request bucket req) ; escape hatch to the raw signed-S3 surface

put hides the single-PUT vs. multipart decision: small objects go up in one request, large objects (and unknown-length streams) are split into parts that upload concurrently and retry individually, so a network blip only costs the part that failed rather than the whole transfer.

get/head/list shadow clojure.core names, so this namespace excludes them; refer to it qualified (e.g. r2/get).

Cloudflare R2 object storage.

R2 speaks the S3 API, so this namespace signs requests with AWS Signature V4
and sends them over the JDK's http client (see the `internal` namespaces) —
no AWS SDK, no dependencies. The public API:

  (bucket m)                ; build a bucket handle
  (put bucket key body)     ; upload an object, multipart automatically
  (get-bytes bucket key)    ; download; also head/exists?/get/get-stream
  (delete bucket key)       ; remove; also delete-many for batches
  (list bucket opts)        ; enumerate by prefix; also list-seq (lazy)
  (presigned-url bucket k)  ; time-limited download/upload URL
  (create-multipart-upload bucket k) ; broker a browser-direct multipart upload
  (request bucket req)      ; escape hatch to the raw signed-S3 surface

`put` hides the single-PUT vs. multipart decision: small objects go up in one
request, large objects (and unknown-length streams) are split into parts that
upload concurrently and retry individually, so a network blip only costs the
part that failed rather than the whole transfer.

`get`/`head`/`list` shadow `clojure.core` names, so this namespace excludes
them; refer to it qualified (e.g. `r2/get`).
raw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
←Move to previous article
→Move to next article
Ctrl+/Jump to the search field
× close