[data-reveal]{opacity:1!important;transform:none!important}
CMS Interfaces

Shared Types

Overview

The types subpath holds the vocabulary every other part of cms-base is built from: the base props interface every component's props extend, the colour and size scales, the action targets a button or a row action can point at, the rule algebra that decides whether a row action applies to a row, the guard signatures a table view runs before a mutation, and a handful of small enums and value unions.

Most of it is exported from one subpath:

import {
  Color,
  FormMode,
  HttpMethod,
  Size,
} from "@antelopejs-private/cms/interfaces/cms-base/types";

Four modules are not re-exported by that barrel and are imported from their own file: types/action-target, types/row-action, types/row-action-operators and types/guards. The guard types and RowActionRule are also re-exported by the table view, so they can equally be imported from @antelopejs-private/cms/interfaces/cms-base.

SymbolsImport from
BaseComponentProps, ButtonVariant, Color, ColorValue, ComponentOrNoInput, CustomButton, CustomButtonSerialized, ButtonColor, ErrorWithMessage, isErrorWithMessage, getErrorMessage, ExportStatus, ListableConfig, FieldMetadata, FormMode, DefaultValue, FormFieldValue, HttpMethod, JsonPrimitive, JsonValue, AxeOrientation, ReadonlyBehavior, ReadonlyBehaviorType, ReadonlyBehaviorConfig, Size, SizeValue, ModalSize, ComponentId, WatchAction, WatchActionCondition, WatchFunctionParamMap, WatchFunctionId, WatchFunctionParams@antelopejs-private/cms/interfaces/cms-base/types
ActionTarget, ActionTargetSerialized@antelopejs-private/cms/interfaces/cms-base/types/action-target
RowActionRule, RowActionConfig, CustomRowAction, CustomRowActionSerialized, FieldEqualsRule, FieldNotEqualsRule, FieldInRule, FieldNotInRule, AndRule, OrRule, NotRule, LogicalRule@antelopejs-private/cms/interfaces/cms-base/types/row-action
FIELD_OPERATORS, FIELD_KEY, FieldOperatorKey, FieldRule, AnyFieldRule, LOGICAL_OPERATOR_KEYS, LogicalOperatorKey@antelopejs-private/cms/interfaces/cms-base/types/row-action-operators
EditGuardArgs, DeleteGuardArgs, BulkGuardArgs, NewGuardArgs, GuardFn, TableViewGuards@antelopejs-private/cms/interfaces/cms-base/types/guards

Base Component Props

BaseComponentProps is the one field every component props interface inherits.

import type { BaseComponentProps } from "@antelopejs-private/cms/interfaces/cms-base/types";

interface BaseComponentProps {
  watchActions?: WatchAction[];
}

FormProps, TreeProps, TabProps, KpiCardProps, ChartCardProps, TopListCardProps, PeriodSelectorProps and the chart props all extend it. The ComponentBuilder from the cms interface strips a caller-supplied watchActions from the options it receives and fills the field itself from .watch() / .watchOn() calls, so the property is the transport rather than something you set by hand.

Watch Actions

A WatchAction binds an event emitted by a component to a function exposed by a component.

import type {
  WatchAction,
  WatchActionCondition,
} from "@antelopejs-private/cms/interfaces/cms-base/types";
FieldTypeDescription
componentstringIdentifier of the component that emits the event. ComponentId.SELF ("$component:self") refers to the declaring component.
eventstringEvent name, e.g. FormEvents.SUBMIT_SUCCESS.
functionIdstringIdentifier of the function to invoke, e.g. FormFunctions.SET_FIELD_HIDDEN.
paramsRecord<string, unknown>Arguments passed to the function.
onParamWatchActionCondition | WatchActionCondition[]Only run when the event payload matches these { key, value } pairs.
requirePermissionstringPermission id the viewer must hold for the action to be kept.

WatchFunctionParamMap is an interface extended by declaration merging: each module that exposes a watch function adds its functionId and the exact parameter shape to the map. WatchFunctionId is keyof WatchFunctionParamMap & string, and WatchFunctionParams<F> resolves to the registered parameter shape for F, falling back to Record<string, unknown> | undefined for ids that are not in the map. Form and TableView both register their functions in this map — see Forms and Tables.

Colors and Sizes

import {
  Color,
  type ColorValue,
  type ModalSize,
  Size,
  type SizeValue,
} from "@antelopejs-private/cms/interfaces/cms-base/types";

Color is an enum of the semantic palette names: primary, secondary, success, info, warning, error, neutral. ColorValue is Color | (string & {}), so a component that accepts a ColorValue takes either an enum member or an arbitrary string while keeping the enum members in editor completion.

Size maps readable names onto the scale tokens: tiny"xs", small"sm", medium"md", large"lg", huge"xl". SizeValue widens it the same way ColorValue widens Color.

ModalSize is a separate, wider union used only for modal action targets: "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl".

Buttons

ButtonVariant is an enum with solid, outline, soft, ghost and link. ButtonColor is a plain string union — "primary" | "secondary" | "success" | "error" | "warning" | "info" | "neutral" — used by CustomButton in place of the Color enum.

CustomButton describes a toolbar button; it is what TableViewOptions.customButtons takes.

import { ButtonVariant } from "@antelopejs-private/cms/interfaces/cms-base/types";
import type { CustomButton } from "@antelopejs-private/cms/interfaces/cms-base/types";

const inviteButton: CustomButton = {
  label: "$page.settings.members.invite.button",
  icon: "i-ph-user-plus",
  variant: ButtonVariant.solid,
  color: "primary",
  target: { type: "page", url: "/settings/users/invite" },
};
OptionTypeDescription
labelstringButton label. Required.
iconstringIcon identifier.
variantButtonVariantVisual variant.
colorButtonColorColour name.
targetActionTargetWhat pressing the button does. Required.
permissionstring | ActionGate the button behind a permission.

permission takes either form: a string names one of the owning table's own actions, as in "add", and an Action references any component's action — another table's add, for instance. A button the caller lacks the permission for is stripped from the serialized options rather than disabled, so it never reaches the browser. A declared permission that cannot be resolved to an id — an action on a page that never registered — fails closed and strips the button too.

CustomButtonSerialized is CustomButton with target replaced by ActionTargetSerialized and permission removed, since the gate is applied server-side before serialization. The table view produces it when it serializes its options.

Action Targets

ActionTarget is a discriminated union on type. It is what a custom button or a custom row action points at.

import type { ActionTarget } from "@antelopejs-private/cms/interfaces/cms-base/types/action-target";
typeFields
"drawer"component: Component, title?, description?
"modal"component: Component, size?: ModalSize, title?, description?
"page"url: string
"external"url: string, newTab?: boolean
"api"url: string, method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH", successMessage: string, confirm?
"exportJob"url: string, method?: "GET" | "POST", statusUrl?, downloadUrl?, labels?, confirm?

The confirm object on the api and exportJob variants is { title: string; description: string; confirmColor?: "primary" | "error" | "warning" }. The labels object on exportJob accepts title, exporting, downloading, successTitle, successMessage, errorTitle and retry, all optional strings.

const validateEmail: ActionTarget = {
  type: "api",
  url: "/settings/user/members/{_id}/validate-email",
  method: "POST",
  successMessage: "$page.settings.members.action.validate_email_success",
  confirm: {
    title: "$page.settings.members.action.validate_email_confirm_title",
    description: "$page.settings.members.action.validate_email_confirm_description",
    confirmColor: "primary",
  },
};

ActionTargetSerialized mirrors the union exactly, with component on the drawer and modal variants replaced by ComponentInfoSerialized.

Row Action Rules

A row action rule decides, per row, whether an action applies. The same rule value is sent to the frontend so the row's menu matches what the backend will accept, and evaluated on the backend before an edit, delete, archive or restore runs.

Field Operators

FIELD_OPERATORS is the catalogue of leaf comparisons. Each entry declares whether the rule value is an array and carries the comparison itself.

import {
  FIELD_KEY,
  FIELD_OPERATORS,
  LOGICAL_OPERATOR_KEYS,
} from "@antelopejs-private/cms/interfaces/cms-base/types/row-action-operators";
KeyisArrayComparison
equalsfalsefieldValue === ruleValue
notEqualsfalsefieldValue !== ruleValue
intrueruleValue.includes(fieldValue)
notIntrue!ruleValue.includes(fieldValue)

FieldOperatorKey is keyof typeof FIELD_OPERATORS. FIELD_KEY is the literal "field", the property name that carries the field name inside a leaf rule. LOGICAL_OPERATOR_KEYS is the tuple ["and", "or", "not"] and LogicalOperatorKey is its element type.

Rule Shapes

A leaf rule is { field: K } plus the operator key. FieldRule<T, Op> builds that shape for one operator over the keys of T, choosing T[K][] for the array operators and T[K] for the others. AnyFieldRule<T> is the union over all four operators.

import type {
  AndRule,
  FieldEqualsRule,
  RowActionRule,
} from "@antelopejs-private/cms/interfaces/cms-base/types/row-action";

interface Invoice extends Record<string, unknown> {
  status: string;
  archived: boolean;
}

const isDraft: FieldEqualsRule<Invoice> = { field: "status", equals: "draft" };

const editable: AndRule<Invoice> = {
  and: [isDraft, { field: "archived", notEquals: true }],
};

The four named leaf aliases are FieldEqualsRule<T>, FieldNotEqualsRule<T>, FieldInRule<T> and FieldNotInRule<T>, each an alias of FieldRule<T, Op> for the matching operator. The three combinators are AndRule<T> ({ and: RowActionRule<T>[] }), OrRule<T> ({ or: RowActionRule<T>[] }) and NotRule<T> ({ not: RowActionRule<T> }); LogicalRule<T> is their union. RowActionRule<T> is AnyFieldRule<T> | LogicalRule<T>, so rules nest to any depth.

Attaching a Rule

RowActionConfig<T> is the object form of a built-in row action.

OptionTypeDescription
isEnabledbooleanWhether the action can be triggered.
isVisiblebooleanWhether the action is shown.
ruleRowActionRule<T>Per-row condition.

CustomRowAction<T> is an extra action in the row menu:

OptionTypeDescription
labelstringMenu label. Required.
iconstringIcon identifier.
targetActionTargetWhat the action does. Required.
ruleRowActionRule<T>Per-row condition.
isVisiblebooleanWhether the action is shown.

CustomRowActionSerialized is the same shape with target: ActionTargetSerialized and an untyped RowActionRule.

Where these are consumed — TableViewOptions.rowActions, and the archive-mode defaults — is covered in Tables.

Guards

A guard is a function the table view calls before a mutating route runs. Throwing from it aborts the operation.

import type {
  GuardFn,
  EditGuardArgs,
  TableViewGuards,
} from "@antelopejs-private/cms/interfaces/cms-base/types/guards";

type GuardFn<TArgs> = (
  this: unknown,
  ctx: RequestContext,
  args: TArgs,
) => void | Promise<void>;

ctx is the RequestContext from @antelopejs/interface-api. this is the data controller instance, so properties declared with @Model are reachable from inside the guard.

InterfaceFields
EditGuardArgs<T>id: string, body: Partial<T>, current: T
NewGuardArgs<T>body: Partial<T>
DeleteGuardArgsids: string[]
BulkGuardArgsids: string[]

TableViewGuards<T> collects one guard per action:

KeyGuard argument
editEditGuardArgs<T>
deleteDeleteGuardArgs
archiveBulkGuardArgs
restoreBulkGuardArgs
newNewGuardArgs<T>

T defaults to Record<string, unknown> on every one of them. How guards are attached and when each one fires is documented in Tables.

Form and Field Types

FormMode

FormMode is the enum new, edit, view. It selects which variant of a form the table view generates and which readonly behaviour applies.

ReadonlyBehavior

ReadonlyBehaviorType is an enum with disabled, hidden and default. ReadonlyBehaviorConfig gives one value per mode:

import { ReadonlyBehaviorType } from "@antelopejs-private/cms/interfaces/cms-base/types";

const createdAtBehavior = {
  new: ReadonlyBehaviorType.hidden,
  edit: ReadonlyBehaviorType.disabled,
  view: ReadonlyBehaviorType.disabled,
};

ReadonlyBehavior is ReadonlyBehaviorType | ReadonlyBehaviorConfig, so a column may pass a single value that applies to every mode or a per-mode object. It is read by ColumnOptions.readonlyBehavior.

ListableConfig and FieldMetadata

FieldMetadata is the slice of a field's data-api metadata the table view reads when it builds a column or a form field.

FieldTypeDescription
mandatorySet<FormMode>Modes in which the field is required.
modeAccessModeAccess mode from @antelopejs/interface-data-api/metadata.
listableListableConfigWhich pluck modes include the field.
sortablebooleanWhether the field can be sorted on.

ListableConfig is { list?: boolean; select?: boolean; export?: boolean } — one flag per pluck mode.

Field Values

DefaultValue and FormFieldValue are the same recursive union: string | number | boolean | Date | null and arrays of themselves. DefaultValue types FormField.defaultValue and ColumnOptions.defaultValue; FormFieldValue types a value held by a form field.

ComponentOrNoInput

type ComponentOrNoInput<T = undefined> = Component<T> | "noInput";

The literal "noInput" stands for a compare mode that takes no value — is_empty and is_not_empty are registered that way, and serializeType substitutes the literal for their filter component. The serialized counterpart used by data types is FilterComponent, documented in Data Types.

Transport and Miscellaneous

HttpMethod

HttpMethod is an enum of GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, keyed by the lowercase name (HttpMethod.get, HttpMethod.post, …). Every component with a fetchUrl also accepts a fetchUrlMethod of this type.

AxeOrientation

AxeOrientation is the enum horizontal / vertical. TabProps.orientation, BarChartProps.orientation and FormComponents.RadioGroupOptions.orientation take it.

ExportStatus

ExportStatus is the enum pending, completed, failed. It is the status stored on an export job and returned by the export-status route — see Helpers.

Json Values

type JsonPrimitive = string | number | boolean | null;
type JsonValue = JsonPrimitive | JsonValue[] | { [key: string]: JsonValue };

JsonValue describes anything that survives a JSON round trip.

Error Helpers

import {
  getErrorMessage,
  isErrorWithMessage,
} from "@antelopejs-private/cms/interfaces/cms-base/types";

try {
  await save();
} catch (error: unknown) {
  if (isErrorWithMessage(error)) {
    // error is narrowed to ErrorWithMessage
  }
  const message = getErrorMessage(error); // "Unknown error" when there is none
}

ErrorWithMessage is { message: string }. isErrorWithMessage is a type guard that accepts any object carrying a message property. getErrorMessage returns that message, or the string "Unknown error" for anything else.

Next Steps

  • Forms - Build a form, its fields, and its validation schema.