[data-reveal]{opacity:1!important;transform:none!important}
Catalog
Interface reference

Catalog

Overview

The catalog is the builder's answer to "what can I put on a page?". GetCatalog returns a BlockCatalog: every block factory the builder knows how to emit, every DataType a form field can use, and the field names a resource may not take. Each entry carries the import the emitter will add and a schema for the options the factory accepts, so you can validate a configuration before you write it.

Read the catalog before AddBlock: the type you pass is a catalog key, and AddBlock rejects a type that is not in it.

Read the Catalog

import { GetCatalog } from "@antelopejs/interface-dms-builder";

const catalog = await GetCatalog();
const kpi = catalog.blocks.find((block) => block.type === "KpiCard");
const containers = catalog.blocks.filter((block) => block.container);
const dataTypeIds = catalog.dataTypes.map((dataType) => dataType.id);

GetCatalog is a read: it returns a BlockCatalog directly, not an OpResult.

FieldTypeDescription
blocksBlockTypeDescriptor[]Every block factory the builder can emit and configure.
dataTypesDataTypeDescriptor[]Every DataType usable as a form field's type.
reservedFieldNamesstring[]Names a resource field may not take.
generatedAtstringCache key, invalidated when the module source changes.

The catalog is cached. RefreshSourceIndex with no scope drops that cache; see Page Operations.

Describe a Block Type

BlockTypeDescriptor is keyed on type, the factory's export name.

FieldTypeDescription
typestringThe factory export name, e.g. KpiCard. This is the catalog key and the value of AddBlockInput.type.
importImportRefThe import the emitter adds for the factory.
containerbooleanWhether the block accepts .child(...).
slotsSlotDescriptor[]The named regions the block exposes, when it has any.
configConfigSchemaA description of the factory's options object.
shapeSourceShapeSourceHow the emit shape was determined.
descriptionstringA human-readable description of the block.
controllerArgbooleantrue when the factory takes a leading controller-class argument before its options object.

Only a container block can hold children, so it is the check to make before passing a block's path as AddBlockInput.parent.

Place a Block in a Slot

A container block may declare named regions. SlotDescriptor describes one:

FieldTypeDescription
idstringThe slot id, passed as AddBlockInput.slot.
descriptionstringWhat the slot is for.
import { GetCatalog } from "@antelopejs/interface-dms-builder";

const catalog = await GetCatalog();
const descriptor = catalog.blocks.find((block) => block.type === "Tab");
const slotIds = descriptor?.slots?.map((slot) => slot.id) ?? [];

Handle a Controller-Leading Block

Some factories take a controller class before their options — TableView(controller, options) is the common case. Those descriptors carry controllerArg: true, and their config describes the second argument, the options object.

A block type with controllerArg: true requires AddBlockInput.controller, naming the resource whose DataAPI class becomes the leading argument; passing controller for any other block type is rejected with invalid_config. Both rules are covered in Page Operations.

import { GetCatalog } from "@antelopejs/interface-dms-builder";

const catalog = await GetCatalog();
const tableView = catalog.blocks.find((block) => block.type === "TableView");
if (tableView?.controllerArg) {
  // AddBlock for this type must carry `controller: "<resource ref>"`.
}

Read a Config Schema

ConfigSchema is a Record<string, unknown> holding a JSON-Schema-shaped description of a block's or DataType's options, generated from its TypeScript type. Keys are option names; each value describes that option — type, enum for a literal union, properties for a nested object, items for an array, oneOf for a union of object shapes.

On top of the standard keys, the schema carries DMS extensions in the x- namespace. The one you act on is x-dataType:

KeyMeaning
x-dataType: trueThe value is a DataType instance (new <DataType>(...)), such as a Form field's type. Pass a DataTypeValue, described in Value Encodings.

An option whose value holds a nested block is marked the same way, with its own x- key. That is rare: most nesting goes through .child, which you express with AddBlockInput.parent rather than through config.

import { GetCatalog } from "@antelopejs/interface-dms-builder";

const catalog = await GetCatalog();
const form = catalog.blocks.find((block) => block.type === "Form");
const fieldsOption = form?.config.fields; // schema for the `fields` option

Resolve an Import

ImportRef is the import the emitter adds when it writes a factory call, a DataType instantiation or a class reference.

FieldTypeDescription
namestringThe imported symbol, e.g. KpiCard or DefaultDataTypes.StringType.
modulestringA package specifier, fixed and independent of the emitting file.
targetFilestringAn absolute path, resolved to a specifier relative to the file being written — used for a reference to a local class such as a generated resource.

A descriptor carries one or the other: module for a symbol that comes from a package, targetFile for one that lives in the project's own source.

Know Where a Shape Came From

ShapeSource is "inferred" | "annotated", and a BlockTypeDescriptor reports which applies to its config:

  • inferred — the shape was read off the factory's TypeScript signature. It is as good as the types are: a well-typed options interface yields a precise schema, while a wide or generic option yields a loose one.
  • annotated — the shape was declared for the builder rather than derived from the signature.

Use shapeSource when deciding how much to trust config. An empty or shallow config on an inferred descriptor means the type could not be described further, not that the factory takes no options.

Choose a DataType

DataTypeDescriptor describes a DataType a form field's type (or a table column's type) can use.

FieldTypeDescription
idstringThe registered id, e.g. string, number, select.
importImportRefThe import the emitter adds for the DataType class.
configConfigSchemaA description of the DataType's options.
descriptionstringA human-readable description.

The id is what you pass as $dataType when writing a value; see Value Encodings. A $dataType the catalog does not list is rejected with invalid_config.

import {
  AddBlock,
  GetCatalog,
} from "@antelopejs/interface-dms-builder";

const catalog = await GetCatalog();
const hasSelect = catalog.dataTypes.some((dataType) => dataType.id === "select");

await AddBlock({
  page: "/customers",
  name: "editor",
  type: "Form",
  config: {
    fields: [
      {
        id: "name",
        label: "Name",
        type: { $dataType: "string" },
      },
    ],
  },
});

Avoid a Reserved Field Name

reservedFieldNames lists the names a resource field may not take: they collide with a generated DataController route or a Model member, and CreateResource or AddField rejects them with invalid_config. Reading them from the catalog saves you carrying your own copy of the list.

import { GetCatalog } from "@antelopejs/interface-dms-builder";

const catalog = await GetCatalog();
const reserved = new Set(catalog.reservedFieldNames);
const fieldName = reserved.has("status") ? "state" : "status";

Resource fields are covered in Resources.

Next Steps

  • Page Operations - Create pages and categories, and edit a page's block tree