@stetcms/client
v0.2.0
Published
Typed content and REST client for Stet, the CMS for marketing and engineering.
Maintainers
Readme
@stetcms/client
Typed client for the API of Stet, the CMS where marketing owns the content model and engineering gets a typed client generated from it. The types come straight from the contract the server implements, so calls and responses are fully typed end to end.
It also carries the content client runtime that @stetcms/vite's generated stet.gen.ts instantiates:
import { createContentClient } from '@stetcms/client';
// Generated code passes a model type here, so `stet.posts` autocompletes and
// each entry's `fields` match the model marketing built.
const stet = createContentClient<Model>({ apiKey: process.env.STET_API_KEY });
const posts = await stet.posts.list();
const post = await stet.posts.get('hello-world');
const landing = await stet.landing.get(); // a map: one entry, no slugRich text fields arrive as markdown, selects as option names, person fields as { id, name }, assets as { id, url, name, contentType, size } whose url is whole and needs no key, and references as { id, slug, title } (an array for multi-reference). Keep the API key server-side: fetch content from loaders, server functions, or your own backend rather than the browser.
Install
npm install @stetcms/clientUsage
import { createStetClient, safe } from '@stetcms/client';
const client = createStetClient({
apiKey: process.env.STET_API_KEY, // organization API key (stet_...)
});
const health = await client.health();
const { data: organization, error } = await safe(client.org.current());
if (error === null) {
console.log(organization.name);
}
const { data: billing } = await safe(client.org.billing());
if (billing !== undefined) {
// usage rows report each measured feature: { feature, used, cap, window }.
console.log(billing.plan, billing.usage);
}API keys are owned by an organization: an org member creates one through the Better Auth api-key endpoints (POST /api/auth/api-key/create with organizationId), and every API call made with that key is scoped to that organization.
Options:
origin: target a local dev server or self-hosted instance (defaults to the hosted deployment).apiKey: organization API key sent asx-api-key.fetch: custom fetch implementation.
The API itself is plain REST under /api/v1, described by the OpenAPI document generated from the same contract. Authentication covers how keys are scoped.
Asset URLs
The API returns asset paths relative to itself; the client joins them to the origin it was created with, so what you get is ready for an img tag on your own origin. That covers an asset field's url and assets embedded or linked inside rich-text markdown and HTML.
Calling the REST API directly instead? assetUrl(url, origin) joins one value and resolveAssetPaths(text, origin) joins the ones inside rich-text markdown or HTML.
License
Apache-2.0
