@clearcms/sdk
v0.3.1
Published
Typed read client for clear. Talk to a clear bucket directly (fs / R2 / S3) or via a running admin's REST API. Same API, same types — pick a backend, get content.
Readme
@clearcms/sdk
Typed read client for clear. Pick a backend, get content. Same API regardless of where the bucket lives.
Status: v0. Read-only. MIT licensed.
Install
pnpm add @clearcms/sdk
# or: npm install @clearcms/sdkBackends
clear stores content as JSON files in a bucket. The bucket can live on disk, in R2, in S3, or behind a running clear admin's REST API. The SDK gives you the same Client shape for all four.
fs — filesystem
Read straight from a bucket directory. No admin running, no network. Perfect for astro build-time reads from a local checkout or a synced R2 mirror.
import { createClient } from '@clearcms/sdk';
const cms = createClient({
backend: 'fs',
root: '/home/me/clear/my-project/bucket',
});
const posts = await cms.collection('posts').list({ locale: 'en' });
const post = await cms.collection('posts').get('hello-world', { locale: 'en' });
const identity = await cms.globals.identity();
const nav = await cms.globals.nav();
const tokens = await cms.theme.tokens();rest — running admin
Talks to a clear admin over HTTP. Lowest-friction backend; requires the admin to be reachable. Drafts/scheduled reads need a token with the read:drafts scope.
const cms = createClient({
backend: 'rest',
adminUrl: 'http://localhost:3000',
token: process.env.CLEAR_API_TOKEN, // optional; required for status !== 'published'
});r2 — Cloudflare R2
S3-compatible HTTPS endpoint, signed via aws4fetch (lightweight, browser+node).
const cms = createClient({
backend: 'r2',
accountId: 'abcd1234...',
bucket: 'my-clear-bucket',
credentials: {
accessKeyId: process.env.R2_ACCESS_KEY_ID!,
secretAccessKey: process.env.R2_SECRET_ACCESS_KEY!,
},
});s3 — generic S3-compatible
Works against AWS S3, MinIO, Backblaze B2, Wasabi, anything that speaks SigV4 + ListObjectsV2.
const cms = createClient({
backend: 's3',
endpoint: 'https://s3.us-east-1.amazonaws.com',
bucket: 'my-clear-bucket',
region: 'us-east-1',
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
});API
interface Client {
collection(name: string): {
list(opts?: { locale?: string; status?: ItemStatus; cache?: CacheMode; signal?: AbortSignal }): Promise<Item[]>;
get(slug: string, opts?: { locale?: string; status?: ItemStatus; cache?: CacheMode; signal?: AbortSignal }): Promise<Item | null>;
};
globals: {
identity(opts?: { cache?: CacheMode; signal?: AbortSignal }): Promise<Identity>;
nav(opts?: { cache?: CacheMode; signal?: AbortSignal }): Promise<Nav>;
};
theme: {
tokens(opts?: { cache?: CacheMode; signal?: AbortSignal }): Promise<ThemeTokens>;
};
}Item, Identity, Nav, ThemeTokens, etc. come from @clearcms/spec — the protocol contract. Re-exported from @clearcms/sdk for convenience.
cache
'no-store' | 'force-cache' | 'default' — mirrors the fetch cache semantics.
- fs: ignored; reads are always fresh.
- rest: forwarded to
fetch'scacheinit field. - r2 / s3: backed by a small per-instance LRU (256 entries).
'no-store'bypasses the cache.
Errors
.get()returnsnullon a clean miss. It does not throw..list()returns[]on a missing prefix.- Network/parse/auth failures throw
ClearSdkErrorwith a tagged.code('transport' | 'parse' | 'config' | 'unauthorized' | 'not-found').
Drafts
In v0, only the REST backend can read drafts (with a read:drafts-scoped token). The bucket-direct backends (fs/r2/s3) deliberately don't surface drafts even when the underlying files exist — drafts are an admin-mediated concern, and serving them from a static mirror would be a footgun. If you need draft reads from a bucket, use the REST backend pointed at the originating admin.
Tree-shaking
Each adapter is a separate module loaded lazily by createClient. A REST-only consumer never imports aws4fetch. A browser bundle never imports node:fs/promises. Bundlers should chunk per backend automatically.
Smoke test
pnpm --filter @clearcms/sdk build
pnpm --filter @clearcms/sdk smoke
# or against a custom admin:
CLEAR_ADMIN_URL=http://localhost:3001 pnpm --filter @clearcms/sdk smokeThe smoke script writes a tiny bucket to os.tmpdir(), exercises the fs adapter against it, and (if an admin is reachable) cross-checks the REST adapter for shape parity.
Status / scope
Shipped:
- Read surface across four backends.
- Single validation gate via
@clearcms/specschemas — the SDK is the same protocol-aware boundary on the read side that the admin'swriteItemFileis on the write side.
Deferred:
- Tests beyond the smoke script (separate agent).
- Bucket-direct draft/scheduled reads.
- FTS / search.
- Media listing.
- Write surface — the SDK is read-only; writes go through the admin.
License
MIT. The SDK is one of the open-source pieces in clear's package split + licensing plan.
