Table Definitions
The Table Class
The Table class serves as the base class for all table definitions. Every table automatically includes an _id field as the primary key.
import { Table, Field } from "@antelopejs/interface-database-decorators";
class User extends Table {
@Field("string")
declare name: string;
@Field("string")
declare email: string;
}
Extend with Modifiers
The Table.with() static method incorporates modifier mixins into the table class, adding capabilities like encryption, hashing, or localization:
import { Table, Field, EncryptionModifier, Encrypted } from "@antelopejs/interface-database-decorators";
class SensitiveData extends Table.with(EncryptionModifier) {
@Field("string")
declare publicContent: string;
@Encrypted({ secretKey: process.env.SECRET_KEY || "default-key" })
@Field("string")
declare secureContent: string;
}
For detailed information about modifiers, see Table Modifiers.
The Index Decorator
The Index decorator marks a field as a database index. Indexed fields enable efficient lookups through getAll() and between() on the underlying AQL table.
import { Table, Field, Index } from "@antelopejs/interface-database-decorators";
class User extends Table {
@Index()
@Field("string")
declare email: string;
@Field("string")
declare name: string;
}
Options
| Option | Type | Description |
|---|---|---|
group | string | Assign the field to a named compound index group. |
Compound Indexes
Assign multiple fields to the same index group to create a compound index:
import { Table, Field, Index, Relation } from "@antelopejs/interface-database-decorators";
class User extends Table {
@Field("string")
declare name: string;
}
class UserActivity extends Table {
@Index({ group: "user_action" })
@Field("string")
@Relation({ to: () => User })
declare userId: string;
@Index({ group: "user_action" })
@Field("string")
declare action: string;
@Field("date")
declare timestamp: Date;
}
The Field Decorator
@Field(type) declares the field type for a property. The type is forwarded verbatim into the TableDefinition.fields map handed to the adapter. It accepts the full FieldType union -- primitive tokens ("string", "number", ...), arrays, nested records, or an io-ts codec.
import * as t from "io-ts";
import { Table, Field, Index, RegisterTable } from "@antelopejs/interface-database-decorators";
@RegisterTable("orders", "shop")
class Order extends Table {
@Field("string")
declare id: string;
@Field(t.union([t.literal("open"), t.literal("closed")]))
declare status: "open" | "closed";
@Index()
@Field("number")
declare total: number;
}
Properties without @Field are omitted from fields. @Field stacks freely with @Index.
The Relation Decorator
The Relation decorator declares a link from a field to another table. It is declarative metadata only: database implementations do not enforce it (no foreign key constraint, no referential validation). Introspection tooling consumes it to expose the links between tables — for example to render schema diagrams or navigate related records.
import { Table, Field, Index, Relation } from "@antelopejs/interface-database-decorators";
class Comment extends Table {
@Index()
@Field("string")
@Relation({ to: () => Post })
declare postId: string;
@Field("string")
@Relation({ to: () => Tag, many: true })
declare tagIds: string[];
}
Options
| Option | Type | Description |
|---|---|---|
to | () => typeof Table | Thunk returning the target table class (lazy to allow forward references). |
toField | string | Target field name. Defaults to the target table's primary key. |
many | boolean | The decorated field holds multiple target keys (many targets per source record). |
@Relation stacks freely with @Field and @Index.
The RegisterTable Decorator
The RegisterTable class decorator associates a table class with a specific table name and schema. This registration is used by RegisterSchema to build the schema definition automatically.
import { Table, Field, Index, RegisterTable } from "@antelopejs/interface-database-decorators";
@RegisterTable("users", "myapp")
class User extends Table {
@Index()
@Field("string")
declare email: string;
@Field("string")
declare name: string;
}
The first argument is the table name in the database, and the second is the schema name.
The Fixture Decorator
The Fixture decorator defines default data to insert when a table is first created. It receives a generator function that produces initial records.
import { Table, Field, Fixture } from "@antelopejs/interface-database-decorators";
@Fixture(() => [
{ _id: "admin", name: "Administrator" },
{ _id: "user", name: "Standard User" },
{ _id: "guest", name: "Guest" },
])
class UserRole extends Table {
@Field("string")
declare name: string;
}
The generator function:
- Receives the table class as its parameter.
- Can return a single object, an array of objects, or a
Promiseresolving to either. - Runs only when the table is empty, preventing duplicate inserts on subsequent starts.
Async Generators
@Fixture(async () => {
const defaults = await loadDefaultConfig();
return defaults.map((cfg) => ({
_id: cfg.key,
value: cfg.value,
}));
})
class SystemConfig extends Table {
@Field("string")
declare value: string;
}
Inheritance
Tables support standard class inheritance. Define a base table with common fields and extend it for specific use cases:
import { Table, Field, Index, Relation } from "@antelopejs/interface-database-decorators";
class BaseEntity extends Table {
@Field("date")
declare createdAt: Date;
@Field("date")
declare updatedAt: Date;
}
class User extends BaseEntity {
@Index()
@Field("string")
declare email: string;
@Field("string")
declare firstName: string;
@Field("string")
declare lastName: string;
}
class Post extends BaseEntity {
@Index()
@Field("string")
@Relation({ to: () => User })
declare authorId: string;
@Field("string")
declare title: string;
@Field("string")
declare content: string;
}
Register a Schema
The RegisterSchema function builds a SchemaDefinition from all tables registered for the given schema id (via @RegisterTable), constructs the Schema (which the adapter provisions), then inserts any fixture data for tables that are empty.
import { RegisterSchema } from "@antelopejs/interface-database-decorators";
await RegisterSchema("myapp");
Parameters
| Parameter | Type | Description |
|---|---|---|
schemaId | string | Schema id matching the @RegisterTable(_, schemaId) declarations. |
RegisterSchema returns Promise<void>.