SlintORM
Docsnpm

TypeScript

SlintORM is written in TypeScript with full generic typing throughout. This page documents every exported type and interface.

ModelAPI<T>

// ModelAPI<T> — all 24 methods
// Returned by orm.defineModel<T>(table, name, hooks?)

interface ModelAPI<T> {
  insert(data: Partial<T>): Promise<EntityWithUpdate<T>>;
  insertMany(data: Partial<T>[]): Promise<EntityWithUpdate<T>[]>;
  get(filter: Partial<T>): Promise<EntityWithUpdate<T> | null>;
  getAll(filter?: Partial<T>): Promise<EntityWithUpdate<T>[]>;
  update(filter: Partial<T>, data: Partial<T>): Promise<number>;
  updateMany(filter: Partial<T>, data: Partial<T>): Promise<number>;
  delete(filter: Partial<T>): Promise<number>;
  deleteMany(filter: Partial<T>): Promise<number>;
  upsert(data: Partial<T>, conflictKey: keyof T): Promise<EntityWithUpdate<T>>;
  findOrCreate(filter: Partial<T>, defaults?: Partial<T>): Promise<{ record: EntityWithUpdate<T>; created: boolean }>;
  exists(filter: Partial<T>): Promise<boolean>;
  count(filter?: Partial<T>): Promise<number>;
  sum(col: keyof T, filter?: Partial<T>): Promise<number>;
  avg(col: keyof T, filter?: Partial<T>): Promise<number>;
  min(col: keyof T, filter?: Partial<T>): Promise<number | string>;
  max(col: keyof T, filter?: Partial<T>): Promise<number | string>;
  truncate(): Promise<void>;
  restore(filter: Partial<T>): Promise<void>;
  validate(data: Partial<T>, rules: FieldRules<T>): Promise<void>;
  check(data: Partial<T>, rules: FieldRules<T>): Promise<Record<string, string> | null>;
  query(): QueryBuilder<T>;
  advanced(): AdvancedQueryBuilder<T>;
  softDelete(): SoftDeleteQueryBuilder<T>;
  extended(): ExtendedQueryBuilder<T>;
}

EntityWithUpdate<T>

// EntityWithUpdate<T>
// Rows returned by get(), insert(), findOrCreate() are augmented with:

type EntityWithUpdate<T> = T & {
  update(data: Partial<T>): Promise<EntityWithUpdate<T>>;
  delete(): Promise<void>;
  refresh(): Promise<EntityWithUpdate<T>>;
  toJSON(): T;
};

// Example:
const user = await User.insert({ email: 'a@b.com', name: 'Alice' });
// user is EntityWithUpdate<User>

const updated = await user.update({ name: 'Bob' });   // -> EntityWithUpdate<User>
await user.delete();                                  // -> void
const fresh = await user.refresh();                   // re-fetches from DB
const plain = user.toJSON();                          // -> User (no ORM methods)

DBStore / ReadonlyDBStore

// DBStore<TModelMap> — typed db object
// Access all models without individual exports

import ORMManager from 'slintorm';
import type { ModelMap } from './schema/generated';

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

export const db: DBStore<ModelMap> = orm.db;

// Fully typed:
db.User.insert(...)      // knows User fields
db.Post.getAll()         // knows Post fields
db.Comment.query()       // QueryBuilder<Comment>
// ReadonlyDBStore<TModelMap>
// Same as DBStore but all models are readonly (no insert/update/delete)
// Useful for passing to functions that should only read

function listUsers(db: ReadonlyDBStore<ModelMap>) {
  return db.User.getAll();  // allowed
  // db.User.insert(...)    // TypeScript error
}

ORMManagerConfig

// ORMManagerConfig<TModelMap>
interface ORMManagerConfig<TModelMap = Record<string, unknown>> {
  driver: DBDriver;
  databaseUrl: string;
  dir?: string;
  logs?: boolean;
  schema?: object;
  modelMap?: TModelMap;
}

type DBDriver = 'sqlite' | 'postgres' | 'mysql' | 'mongodb';

Utility types

// Utility types

// SQLExecResult — returned by adapter.exec()
interface SQLExecResult {
  rows: unknown[];
  rowsAffected: number;
  lastInsertId: number | null;
}

// ExecFn — the adapter's core execute function
type ExecFn = (sql: string, params?: unknown[]) => Promise<SQLExecResult>;

// OpComparison — valid WHERE operators
type OpComparison = '=' | '!=' | '<' | '<=' | '>' | '>=' | 'LIKE' | 'ILIKE';

// RelationKind — valid relation types
type RelationKind = 'onetomany' | 'manytoone' | 'onetoone' | 'manytomany';

// RelationDef — parsed from @relation annotations
interface RelationDef {
  kind: RelationKind;
  modelName: string;
  foreignKey: string;
  relatedKey?: string;
  through?: string;
  onDelete?: 'CASCADE' | 'SET NULL';
}

FieldMeta

// FieldMeta — parsed annotation data per field
// Used internally by Migrator and QueryBuilder

interface FieldMeta {
  auto?: boolean;
  primaryKey?: boolean;
  unique?: boolean;
  index?: boolean;
  nullable?: boolean;
  notNull?: boolean;
  length?: number;
  json?: boolean;
  softDelete?: boolean;
  enum?: string[];
  default?: string;
  comment?: string;
  relation?: RelationDef;
}

FieldRules / ModelHooks

// FieldRules<T> — per-field validation rules

type FieldRules<T> = {
  [K in keyof T]?: {
    required?: boolean;
    email?: boolean;
    minLength?: number;
    maxLength?: number;
    min?: number;
    max?: number;
    match?: RegExp;
    custom?: (value: unknown, row: Partial<T>) => string | null | Promise<string | null>;
  };
};

// ModelHooks<T> — lifecycle hooks
interface ModelHooks<T> {
  onCreateBefore?: (data: T) => T | void | Promise<T | void>;
  onCreateAfter?: (item: T) => void | Promise<void>;
  onUpdateBefore?: (oldData: T, newData: Partial<T>) => Partial<T> | void | Promise<Partial<T> | void>;
  onUpdateAfter?: (oldData: T, newData: Partial<T>) => void | Promise<void>;
  onDeleteBefore?: (deleted: T) => void;
  onDeleteAfter?: (deleted: T) => void;
}

ModelMap pattern

// ModelMap pattern — generated by 'npx slintorm generate'

// src/schema/generated.ts (auto-generated — do not edit)
export const ModelMap = {
  User: {} as ModelAPI<User>,
  Post: {} as ModelAPI<Post>,
  Comment: {} as ModelAPI<Comment>,
  Team: {} as ModelAPI<Team>,
};

export type ModelMap = typeof ModelMap;

// Usage in db.ts:
import ORMManager from 'slintorm';
import type { ModelMap } from './schema/generated';

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

// orm.db is typed as DBStore<ModelMap>
// orm.db.User, orm.db.Post, etc. are all fully typed
PreviousDriversNextSchema Generation