@saacms/storage-r2
v0.1.9
Published
Cloudflare R2 storage adapter for saacms. Implements the `StorageAdapter` interface (`{ put, get, delete, signedUrl }`) over a Workers `R2Bucket` binding, for use by Media Collections in `bucket` storage mode.
Readme
@saacms/storage-r2
Cloudflare R2 storage adapter for saacms. Implements the StorageAdapter interface ({ put, get, delete, signedUrl }) over a Workers R2Bucket binding, for use by Media Collections in bucket storage mode.
See ADR 0009 — Media as Collection kind for the storage-adapter interface and the bucket vs repo modes, and ADR 0024 — v1 alpha scope for why R2 is the v1 default bucket.
Status
Scaffold. The put / get / delete operations forward to the R2Bucket binding the host passes in. signedUrl returns a public URL when publicBaseUrl is configured; pre-signed URL generation (AWS SigV4 over R2's S3 endpoint, via aws4fetch) is deferred until ADR 0009's open question on transform URL syntax is resolved.
Usage (target shape)
// saacms.config.ts
import { defineConfig } from "saacms"
import { r2Adapter } from "@saacms/storage-r2"
export default defineConfig({
storage: r2Adapter({
bucket: env.SAACMS_MEDIA, // R2Bucket binding from wrangler.toml
prefix: "media/",
publicBaseUrl: "https://cdn.example.com",
}),
})The bucket field is the Workers R2 binding object — saacms doesn't open the binding for you; the host (Astro on Cloudflare Pages, per ADR 0024) injects it from wrangler.toml.
Known reconciliation TODO
The local StorageAdapter interface in src/r2-adapter.ts is a copy with TODO. Replace with import type { StorageAdapter } from "@saacms/core" once the cross-package contract test (per ADR 0019) is wired up to enforce conformance.
