CMS / foldkit-cms

Example

This integration extends an existing Entity, form, and pair of Remote mutations. Blog.Post, PostForm, CreatePostMutation, and UpdatePostMutation come from your domain module; the example domain shows those definitions together. Start with Form if you have not yet defined the operation's input.

ts
import { Cms } from 'foldkit-cms'

// Which members play a CMS part is a fact about the Entity: metadata, by a pipe step.
const Post = Blog.Post.pipe(
  Cms.roles({ label: 'title', slug: 'slug', published: 'publishedAt' }),
)

// How a type of content is authored is a fact about the application.
const Posts = Cms.content('posts', {
  entity: Post,
  form: PostForm, // an ordinary form: Form.make('PostForm', Entity.input(Post, PostInput))
  publish: { create: CreatePostMutation, update: UpdatePostMutation },
  words: { one: 'Post', many: 'Posts' },
  // Optional: how a value would look in the store, for in-app preview.
  preview: (value, id) => [{ entity: 'Post', id, values: value }],
})
  • Post is the same Entity as Blog.Post; only its metadata changed. Register and bind the annotated one.
  • A role names a member that can play it. slug on a number, or published on a field that admits no null, is a type error and throws.
  • publish.create's input is the form's value and its output names the row; publish.update's input is that value and the row's id. A mutation of another shape is a type error. They are your own mutations: what publishing a post does stays your code.
  • A capability is declared, never implied. No slug role, no slug handling. No published role, no unpublish, and every row is visible.

Cms.rolesOf(Post) reads the roles back as Fields. Anything may: the server's audience policy, a bySlug query, a sitemap this package knows nothing of.