CMS Base Documentation
Overview
The cms-base interface is the component vocabulary of the CMS: forms, tables, charts and cards, layout containers, trees, the data types behind every field, and the shared prop types they all draw from.
Every component here is a builder. Form({...}), TableView(controller, {...}) and ChartLine({...}) do not render anything — they return a ComponentBuilder from the cms interface, which is a serializable description of a component: its name, its options, and its children. You assign that description to a static field of a page class, and the frontend reads the page's tree and draws it. The options you set are therefore data, and the components that need data are given a fetchUrl and a submitUrl pointing back at routes you declare on the same page or on a data controller.
Two consequences shape the whole interface. First, a component's contract is its props interface: what you can express is exactly what the props allow, which is why this reference documents them field by field. Second, anything the frontend must receive has to survive serialization, so a builder that accepts a nested Component — a modal target, a kanban card, a chart inside a card — stores its serialized form instead.
The CMS documentation carries task-shaped chapters on the same components, organised around what you are building. This folder is the contract behind them: the exact symbol names, option fields and return types.
Subpath Map
@antelopejs-private/cms/interfaces/cms-base is the root barrel and re-exports most of the modules below. The ones marked as not in the barrel are imported from their own subpath.
| Subpath | Holds | In the root barrel | Documented in |
|---|---|---|---|
types | Base props, colours, sizes, buttons, action targets, row-action rules, guards, watch actions, enums | yes | Shared Types |
form | Form, FormComponents, schema helpers | yes | Forms |
table-view | TableView, @Column, TableViewRoutes, guards, row actions | yes | Tables |
chart | Chart builders, series and point shapes, chart props | yes | Charts and Widgets |
chart-card | ChartCard | yes | Charts and Widgets |
kpi-card | KpiCard | yes | Charts and Widgets |
top-list-card | TopListCard | yes | Charts and Widgets |
period-selector | PeriodSelector | yes | Charts and Widgets |
grid | Grid, GridRow | yes | Layout and Containers |
stack | HStack, VStack, Spacer | yes | Layout and Containers |
tab | Tab | yes | Layout and Containers |
layouts | DefaultLayout, EmptyLayout | yes | Layout and Containers |
placeholder | Placeholder | yes | Layout and Containers |
custom | CustomComponent | no | Layout and Containers |
tree | Tree, TreeNode, TreeEvents | yes | Tree |
data-types | DataType, the registration decorators, DefaultDataTypes, DefaultDataCompareTypes, StatusType | no | Data Types |
searchable | Searchable, SearchableMeta | yes | Helpers |
export-jobs | runExportJob and the export-job lifecycle | yes | Helpers |
tenant-export-archive | startTenantExportJob, buildTenantExportArchive | yes | Helpers |
helpers/file-refs | File and image reference tracking | no | Helpers |
helpers/archive-mode-helpers | applyArchiveModeDefaultRules | no | Helpers |
Within types, four modules are outside that subpath's barrel and are imported from types/action-target, types/row-action, types/row-action-operators and types/guards; the guard types and RowActionRule are also re-exported by table-view.
Key Features
- Builders that produce data — Every component function returns a
ComponentBuilder, so a page's UI is a plain value you can factor, reuse and compose with.child(). - Forms from typed fields — A field names a
DataType, and the type supplies both the input component and the Zod schema;Formcompiles the field list into one schema and ships its JSON Schema form with the component. - Tables from data controllers —
TableViewreads a controller's data-api metadata and its@Columndeclarations to build the columns, thenew/edit/viewforms, and the permission-carrying actions in one call. - Server-enforced row rules and guards — Row-action rules are a small algebra evaluated on both sides, and guards run inside the mutating routes, so what the row menu offers is what the server accepts.
- A chart and widget set with a shared period scope — Twelve chart types plus KPI, chart and top-list cards; one
PeriodSelectorid ties them to the same range and comparison. - Layout without a frontend build — Grids, stacks, tabs and page layouts arrange components, and
CustomComponentnames a Vue component when the vocabulary runs out. - An extensible data-type registry —
@RegisterDataTypeand@RegisterDataCompareModeadd your own types and filter operators to the catalogue the forms, columns and filters draw from. - Shared prop vocabulary — Colours, sizes, HTTP methods, action targets, readonly behaviour and watch actions are declared once in
typesand reused by every component.
Dependencies
This interface relies on the following AntelopeJS packages:
- @antelopejs/interface-api - Request context, controller metadata and route parameters.
- @antelopejs/interface-api-util -
assertfor failing a route with an HTTP status. - @antelopejs/interface-core - Metadata storage, decorator factories, interface functions and logging.
- @antelopejs/interface-data-api - Data controllers, default routes, list parameters and field metadata.
- @antelopejs/interface-database - The value proxies compare modes build their filters from.
- @antelopejs/interface-database-decorators - Models and the localization modifier.
- @antelopejs/interface-file-storage - Upload constraints, staged-key promotion and file deletion behind the file and image types.
- zod and zod-to-json-schema - Field validation schemas and their JSON Schema form.
It also builds on sibling interfaces of the same package: cms/component for Component and ComponentBuilder, cms/page for the page a component is registered on, cms/permissions for the action permissions a table view declares, and cms-auth for the authenticated user its routes receive.
Quick Start
A page declaring one component. The Form builder describes the fields; the two routes on the same class serve and accept the values.
import { Get, JSONBody, Post } from "@antelopejs/interface-api";
import { GetModel } from "@antelopejs/interface-database-decorators";
import {
PageController,
pagesCategory,
RegisterPage,
} from "@antelopejs-private/cms/interfaces/cms/page";
import { DefaultDataTypes } from "@antelopejs-private/cms/interfaces/cms-base/data-types";
import { Form } from "@antelopejs-private/cms/interfaces/cms-base/form";
import { DefaultLayout } from "@antelopejs-private/cms/interfaces/cms-base/layouts";
import { HttpMethod } from "@antelopejs-private/cms/interfaces/cms-base/types";
import { SettingsModel } from "./db";
@RegisterPage()
export class SettingsPage extends PageController(
"settings",
{
urlSlug: "settings",
displayName: "Settings",
description: "Module configuration",
icon: "i-ph-gear",
category: pagesCategory,
},
DefaultLayout(),
) {
static form = Form({
title: "Settings",
fetchUrl: "/settings/",
submitUrl: "/settings/",
submitUrlMethod: HttpMethod.post,
fields: [
{
id: "enabled",
label: "Enabled",
type: new DefaultDataTypes.BooleanType(),
},
{
id: "retentionDays",
label: "Retention (days)",
type: new DefaultDataTypes.NumberType({ min: 0 }),
required: true,
},
],
});
settingsModel = GetModel(SettingsModel);
@Get("/")
read() {
return this.settingsModel.get();
}
@Post("/")
async write(@JSONBody() body: unknown) {
await this.settingsModel.table.update(body as Record<string, unknown>);
}
}
The page registers itself at import time, and its routes are mounted under the page's slug — which is why the form fetches from and submits to /settings/. Nothing else is needed: Form has already serialized each field into an input-component description and compiled the two data types into one schema, which it carries in the component options alongside the URLs.
Documentation Sections
- Shared Types - Base props, colours, sizes, action targets, row-action rules, guards and the small enums.
- Forms - The
Formbuilder, fields and groups, input components and the validation schema. - Tables - Table views over a data controller: columns, routes, row actions, guards, displays and generated forms.
- Charts and Widgets - Chart types and props, chart cards, KPI cards, top lists and the period selector.
- Layout and Containers - Grids, stacks, tabs, page layouts, the placeholder and the custom-component escape hatch.
- Tree - Hierarchical nodes, selection behaviour and lazy loading.
- Data Types - The
DataTypecontract, the registries, the default catalogue and a custom type. - Helpers - Searchable columns, export jobs, file references and the archive-mode defaults.