Damat

5. Defining models (the ORM DSL)

Models are defined with a fluent, type-safe DSL from @damatjs/orm-model. model(table, columns) returns a definition you can refine with .indexes(), .constrain(), .timestamps(), and .softDelete().

import { model, columns } from "@damatjs/orm-model";

export const UserModel = model("users", {
  id: columns.id({ prefix: "usr" }).primaryKey(),
  email: columns.text().unique(),
  emailVerified: columns.boolean().default(false),
  name: columns.text().nullable(),
  image: columns.text().nullable(),

  // relations reference the target table name
  accounts: columns.hasMany("accounts"),
  sessions: columns.hasMany("sessions"),
}).indexes([
  columns.indexes().columns(["email"]).unique(),
]);

export default UserModel;

Columns

The DSL covers the PostgreSQL type system. Common builders:

GroupBuilders
Identityid({ prefix? }), uuid()
Stringstext(), varchar(length?), char(length?)
Numbersinteger(), numeric(precision?, scale?), real(), doublePrecision(), money()
Booleanboolean()
Temporaltimestamp({ withTimezone? }), date(), time(), interval()
JSONjson(), jsonb()
Binarybytea()
Enumenum(values)
Vectorvector(dimensions) — pgvector
RelationsbelongsTo(target), hasMany(target), hasOne(target)

Modifiers chain: .primaryKey(), .unique(), .nullable(), .default(value), .defaultNow(), .length(n), .name("col_name"), .autoincrement(). See the orm-model column reference for the complete list and exact semantics.

Relations, indexes, constraints

export const AccountModel = model("accounts", {
  id: columns.id({ prefix: "acc" }).primaryKey(),
  userId: columns.text(),
  provider: columns.text(),
  user: columns.belongsTo("users"),   // FK -> users
})
  .indexes([columns.indexes().columns(["userId"])])
  .timestamps();                       // adds createdAt / updatedAt

Relations like belongsTo/hasMany are for tables within one module. To relate models that live in different modules, use a cross-module link instead (src/links/, with defineLink/collectLinkModels/defineLinkModule) so neither module depends on the other — see Concepts → How modules compose, the default backend, and the full @damatjs/link reference.

Once models change, generate and apply a migration.