SlintORM
Docsnpm

defineModel

orm.defineModel<T>(table, modelName, hooks?) registers a model and returns a ModelAPI<T>with 24 methods for querying and mutating that table.

Manual export pattern

db.ts
// db.ts
import ORMManager from 'slintorm';

interface User {
  id: number;
  email: string;
  name: string;
}

interface Post {
  id: number;
  title: string;
  userId: number;
}

const orm = new ORMManager({ driver: 'sqlite', databaseUrl: './dev.db' });
await orm.migrate();

// Export each model individually
export const User = orm.defineModel<User>('users', 'User');
export const Post = orm.defineModel<Post>('posts', 'Post');

With lifecycle hooks

db.ts
// db.ts — defineModel with hooks
import bcrypt from 'bcrypt';

interface User {
  id: number;
  email: string;
  password: string;
  name: string;
}

export const User = orm.defineModel<User>('users', 'User', {
  async onCreateBefore(data) {
    // Hash password before insert — returned value replaces the record
    return { ...data, password: await bcrypt.hash(data.password, 10) };
  },
  async onCreateAfter(item) {
    console.log('User created:', item.id);
  },
  async onUpdateBefore(oldData, newData) {
    if (newData.password) {
      return { ...newData, password: await bcrypt.hash(newData.password, 10) };
    }
  },
  async onUpdateAfter(oldData, newData) {
    console.log(`User ${oldData.id} updated`);
  },
  onDeleteBefore(deleted) {
    console.log('Deleting user:', deleted.id);
  },
  onDeleteAfter(deleted) {
    console.log('User deleted:', deleted.id);
  },
});

ModelMap pattern

For larger projects, use the generated ModelMap to get a typed db store without needing to export each model individually.

db.ts
// db.ts — ModelMap pattern (recommended for large projects)
import ORMManager from 'slintorm';
import type { ModelMap } from './schema/generated';

const orm = new ORMManager<ModelMap>({
  driver: 'sqlite',
  databaseUrl: './dev.db',
  modelMap: {} as ModelMap,
});

await orm.migrate();

// Access all models through the typed db store
export const db = orm.db;

// Usage:
// db.User.insert({ email: 'a@b.com', name: 'Alice' })
// db.Post.getAll()

EntityWithUpdate methods

Every row returned by get(), insert(), findOrCreate(),getAll(), and all query builder methods (query().get(), query().first()) is augmented with convenience methods for mutation and refresh.

example.ts
// EntityWithUpdate<T> — methods on returned rows

const user = await User.get({ email: 'joe@example.com' });
// user is EntityWithUpdate<User> | null

if (user) {
  // .update(partial) — updates in DB, returns updated entity
  const updated = await user.update({ name: 'Joseph' });

  // .delete() — deletes from DB (or soft-deletes if @softDelete)
  await user.delete();

  // .refresh() — re-fetches from DB, returns updated snapshot
  const fresh = await user.refresh();

  // .toJSON() — strips ORM methods, returns plain object
  const plain = user.toJSON();
}

ModelAPI method reference

All 24 methods available on every model instance:

MethodDescription
insert(data)Insert a row, returns EntityWithUpdate<T>
insertMany(data[])Batch insert rows, wrapped in a transaction on SQLite
get(filter)Get first matching row or null
getAll(filter?)Get all matching rows
update(filter, data)Update matching rows, auto-sets updatedAt
updateMany(filter, data)Batch update, returns number of affected rows
delete(filter)Delete matching rows (hard delete or soft delete)
deleteMany(filter)Batch delete, returns number of affected rows
upsert(data, conflictKey)Insert or update on conflict
findOrCreate(filter, defaults?)Find or insert, returns { record, created }
exists(filter)Returns boolean — true if any row matches
count(filter?)Count matching rows
sum(col, filter?)Scalar SUM of a column
avg(col, filter?)Scalar AVG of a column
min(col, filter?)Scalar MIN of a column
max(col, filter?)Scalar MAX of a column
truncate()Delete all rows
restore(filter)Un-delete soft-deleted rows
validate(data, rules)Validate data, throws ValidationError on failure
check(data, rules)Validate data, returns error map or null
query()Returns a QueryBuilder<T> for fluent query building
advanced()Returns an AdvancedQueryBuilder<T> (aggregates, window functions)
softDelete()Returns a SoftDeleteQueryBuilder<T> (withTrashed, onlyTrashed)
extended()Returns an ExtendedQueryBuilder<T> with scope() support
PreviousModelsNextCRUD