Model Definition API

Define models with columns, relationships, scopes, and options

defineModel()

defineModel<T>(config: ModelConfig): Model<T>
export interface ModelConfig {
tableName: string;
versioned?: boolean;
softDelete?: boolean;
columns: Record<string, ColumnConfig>;
relations?: RelationConfig[];
scopes?: Record<string, (qb: QueryBuilder<any>, ...args: any[]) => QueryBuilder<any>>;
timestamps?: TimestampsConfig;
}

Defines a new model with its schema, relationships, scopes, and options.

Model Definition Options:

  • tableName Database table name (required)
  • columns Column definitions (required)
  • relations Relationship definitions (optional)
  • scopes Custom query scopes (optional)
  • timestamps Auto-manage createdAt/updatedAt (optional)
  • softDelete Enable soft deletes with deletedAt (optional)
  • versioned Enable version tracking (optional)
models/User.tstypescript
import { defineModel, DataTypes, RelationType } from "stabilize-orm";
const User = defineModel({
tableName: "users",
timestamps: { createdAt: "createdAt", updatedAt: "updatedAt" },
softDelete: true,
versioned: true,
columns: {
id: {
type: DataTypes.Integer,
primaryKey: true,
autoIncrement: true,
},
email: {
type: DataTypes.String,
length: 100,
required: true,
unique: true,
index: "idx_email"
},
name: {
type: DataTypes.String,
length: 255,
required: true,
},
deletedAt: {
type: DataTypes.DateTime,
softDelete: true,
}
},
relations: [
{
type: RelationType.OneToMany,
target: () => Post,
property: "posts",
foreignKey: "userId",
}
],
scopes: {
active: qb => qb.where("isActive = ?", true),
}
});

Column Options

Available options for column definitions:

export interface ColumnConfig {
name?: string;
type: DataTypes;
length?: number;
precision?: number;
scale?: number;
required?: boolean;
unique?: boolean;
defaultValue?: any;
index?: string;
softDelete?: boolean;
}
  • type Data type (required)
  • primaryKey Mark as primary key
  • autoIncrement Auto-increment for integers
  • required NOT NULL constraint
  • unique UNIQUE constraint
  • defaultValue Default value or function
  • length Max length for strings
  • precision Precision for decimals
  • scale Scale for decimals
  • index Index name (optional)
  • softDelete Marks column as soft delete field
models/Product.tstypescript
columns: {
id: { type: DataTypes.Integer, primaryKey: true, autoIncrement: true },
email: { type: DataTypes.String, length: 100, required: true, unique: true, index: "idx_email" },
price: { type: DataTypes.Decimal, precision: 10, scale: 2, defaultValue: 0 },
createdAt: { type: DataTypes.DateTime, defaultValue: () => new Date() },
deletedAt: { type: DataTypes.DateTime, softDelete: true }
}

Relationship Options

Define relationships between models:

export interface RelationConfig {
type: RelationType;
target: () => any;
property: string;
foreignKey?: string;
inverseKey?: string;
joinTable?: string;
}
  • type RelationType (OneToOne, OneToMany, ManyToOne, ManyToMany)
  • target Target model function
  • property Property name for the relation
  • foreignKey Foreign key column name
  • inverseKey Inverse key (OneToMany, ManyToMany)
  • joinTable Junction table (ManyToMany only)
models/User.tstypescript
relations: [
{
type: RelationType.OneToMany,
target: () => Post,
property: "posts",
foreignKey: "userId",
},
{
type: RelationType.ManyToMany,
target: () => Role,
property: "roles",
joinTable: "user_roles",
foreignKey: "userId",
inverseKey: "roleId",
},
]

Timestamps & Scopes

Auto-managed timestamp columns and custom query scopes:

export interface TimestampsConfig {
createdAt?: string;
updatedAt?: string;
}
scopes: {
[name: string]: (qb: QueryBuilder<any>, ...args: any[]) => QueryBuilder<any>
}
models/User.tstypescript
const User = defineModel({
tableName: "users",
timestamps: { createdAt: "createdAt", updatedAt: "updatedAt" },
scopes: {
active: qb => qb.where("isActive = ?", true),
byEmail: (qb, email) => qb.where("email = ?", email)
}
});