or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

bookshelf-instance.mdcollections.mdevents.mdindex.mdmodels.mdquery-building.mdrelationships.md
tile.json

index.mddocs/

Bookshelf

Bookshelf is a JavaScript ORM for Node.js built on the Knex SQL query builder. It provides both Promise-based and traditional callback interfaces, transaction support, eager/nested-eager relation loading, polymorphic associations, and support for one-to-one, one-to-many, and many-to-many relations.

Package Information

  • Package Name: bookshelf
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install bookshelf knex (plus database driver: pg, mysql, or sqlite3)

Core Imports

const knex = require('knex')(dbConfig);
const bookshelf = require('bookshelf')(knex);

Basic Usage

const knex = require('knex')({
  client: 'mysql',
  connection: {
    host: '127.0.0.1',
    user: 'your_db_user',
    password: 'your_password',
    database: 'myapp'
  }
});
const bookshelf = require('bookshelf')(knex);

// Define a model
const User = bookshelf.model('User', {
  tableName: 'users',
  posts() {
    return this.hasMany('Post');
  }
});

const Post = bookshelf.model('Post', {
  tableName: 'posts',
  user() {
    return this.belongsTo('User');
  }
});

// Use the models
const user = await new User({name: 'Alice'}).save();
const userWithPosts = await new User({id: 1}).fetch({withRelated: ['posts']});

Architecture

Bookshelf is built around several key components:

  • Bookshelf Instance: Created by passing a Knex instance, provides Model/Collection constructors and registry
  • Model Layer: Individual database rows with attribute management, relations, and lifecycle events
  • Collection Layer: Ordered sets of models with array-like methods and bulk operations
  • Relation System: Comprehensive relationship definitions including polymorphic associations
  • Event System: Lifecycle events for models and collections with Promise support
  • Query Builder Integration: Full access to underlying Knex query builder for complex queries

Capabilities

Bookshelf Instance

Core Bookshelf instance initialization and configuration, including model registry and plugin system.

/**
 * Creates a new Bookshelf instance
 * @param {Knex} knex - Initialized Knex client instance
 * @returns {Bookshelf} Bookshelf instance
 */
function Bookshelf(knex);

// Instance properties and methods
interface BookshelfInstance {
  VERSION: string;
  knex: Knex;
  Model: ModelConstructor;
  Collection: CollectionConstructor;
  
  model(name: string): Model;
  model(name: string, Model: ModelConstructor, staticProperties?: object): Model;
  collection(name: string): Collection;
  collection(name: string, Collection: CollectionConstructor, staticProperties?: object): Collection;
  resolve(name: string): any;
  transaction(callback: (transaction: Transaction) => Promise<any>): Promise<any>;
  plugin(plugin: string | Function | Array, options?: any): BookshelfInstance;
}

Bookshelf Instance

Model Operations

Complete CRUD operations, query building, and attribute management for individual database records.

// Static methods
interface ModelStatic {
  forge(attributes?: object, options?: object): Model;
  collection(models?: Model[], options?: object): Collection;
  count(column?: string, options?: object): Promise<number>;
  fetchAll(options?: object): Promise<Collection>;
  fetchPage(options?: object): Promise<{models: Collection, pagination: object}>;
  where(...args: any[]): Model;
  query(...args: any[]): Model;
}

// Instance methods
interface ModelInstance {
  fetch(options?: {withRelated?: string[], require?: boolean, transacting?: Transaction, columns?: string[], debug?: boolean}): Promise<Model>;
  save(key?: string | object, value?: any, options?: {method?: 'insert'|'update', patch?: boolean, transacting?: Transaction, debug?: boolean}): Promise<Model>;
  destroy(options?: {require?: boolean, transacting?: Transaction, debug?: boolean}): Promise<Model>;
  get(attribute: string): any;
  set(key: string | object, value?: any, options?: {unset?: boolean, silent?: boolean}): Model;
  has(attribute: string): boolean;
  unset(attribute: string, options?: object): Model;
  clear(options?: object): Model;
  isNew(): boolean;
  hasChanged(attribute?: string): boolean;
  previous(attribute?: string): any;
  previousAttributes(): object; 
  related(relationName: string): Model | Collection;
  clone(): Model;
  refresh(options?: {transacting?: Transaction}): Promise<Model>;
  toJSON(options?: {shallow?: boolean, omitPivot?: boolean}): object;
}

Models

Collection Operations

Array-like operations and bulk database operations for sets of models.

// Static methods
interface CollectionStatic {
  forge(models?: any[], options?: object): Collection;
}

// Instance methods  
interface CollectionInstance {
  fetch(options?: {withRelated?: string[], require?: boolean, transacting?: Transaction, debug?: boolean}): Promise<Collection>;
  fetchOne(options?: {require?: boolean, transacting?: Transaction}): Promise<Model>;
  fetchPage(options?: {page?: number, pageSize?: number, limit?: number, offset?: number, withRelated?: string[]}): Promise<{models: Collection, pagination: object}>;
  add(models: Model | Model[], options?: {at?: number, merge?: boolean, silent?: boolean}): Collection;
  remove(models: Model | Model[], options?: {silent?: boolean}): Collection;
  reset(models?: Model[], options?: {silent?: boolean}): Collection;
  create(attributes: object, options?: {wait?: boolean, transacting?: Transaction}): Promise<Model>;
  at(index: number): Model;
  get(id: any): Model;
  first(): Model;
  last(): Model;
  pluck(attribute: string): any[];
  where(attributes: object): Model[];
  clone(): Collection;
  length: number;
  models: Model[];
}

Collections

Relationships

Comprehensive relationship definitions including one-to-one, one-to-many, many-to-many, and polymorphic associations.

// Relation methods (available on Model instances)
interface RelationMethods {
  hasOne(Target: string | ModelConstructor, foreignKey?: string, foreignKeyTarget?: string): Relation;
  hasMany(Target: string | ModelConstructor, foreignKey?: string, foreignKeyTarget?: string): Relation;
  belongsTo(Target: string | ModelConstructor, foreignKey?: string, foreignKeyTarget?: string): Relation;
  belongsToMany(Target: string | ModelConstructor, tableName?: string, foreignKey?: string, otherKey?: string, foreignKeyTarget?: string, otherKeyTarget?: string): Relation;
  morphOne(Target: string | ModelConstructor, name: string, columnNames?: string[], morphValue?: any): Relation;
  morphMany(Target: string | ModelConstructor, name: string, columnNames?: string[], morphValue?: any): Relation;  
  morphTo(relationName: string, columnNames?: string[], ...targets: any[]): Relation;
  through(Interim: string | ModelConstructor, throughForeignKey?: string, otherKey?: string, throughForeignKeyTarget?: string, otherKeyTarget?: string): Relation;
}

Relationships

Events System

Lifecycle events for models and collections with both synchronous and asynchronous event handling.

// Event methods (available on Models and Collections)
interface EventMethods {
  on(events: string, callback: Function): this;
  off(events?: string, callback?: Function): this;
  trigger(event: string, ...args: any[]): this;
  triggerThen(event: string, ...args: any[]): Promise<any>;
  once(events: string, callback: Function): this;
}

// Model events: 'fetching', 'fetched', 'saving', 'creating', 'updating', 'saved', 'created', 'updated', 'destroying', 'destroyed'
// Collection events: 'fetched', 'add', 'remove', 'reset', 'sort', 'creating', 'attaching', 'attached', 'detaching', 'detached'

Events

Query Building

Direct access to Knex query builder for complex database operations and custom queries.

// Query building methods (available on Models and Collections)
interface QueryMethods {
  query(callback?: (qb: Knex.QueryBuilder) => void): this;
  where(...args: any[]): this;
  orderBy(column: string, direction?: string): this;
}

Query Building

Transactions

Database transaction support with automatic rollback on errors and connection management.

/**
 * Execute operations within a database transaction
 * @param {Function} callback - Transaction callback function receiving transaction object
 * @returns {Promise<any>} Promise resolving to callback result
 */
transaction(callback: (transaction: Transaction) => Promise<any>): Promise<any>;

Plugin System

Extend Bookshelf functionality with community and custom plugins.

/**
 * Load one or more plugins into this Bookshelf instance
 * @param {string|Function|Array} plugin - Plugin name, function, or array of plugins
 * @param {any} [options] - Plugin configuration options
 * @returns {BookshelfInstance} This Bookshelf instance for chaining
 */
plugin(plugin: string | Function | Array, options?: any): BookshelfInstance;

Error Types

Bookshelf provides specific error classes for common database operation failures.

// Available error classes (accessible via bookshelf instance)
interface ErrorTypes {
  NotFoundError: ErrorConstructor;        // Model/Collection not found with require: true
  EmptyError: ErrorConstructor;          // Collection is empty when required
  NoRowsUpdatedError: ErrorConstructor;  // Update operation affected no rows
  NoRowsDeletedError: ErrorConstructor;  // Delete operation affected no rows  
  ModelNotResolvedError: ErrorConstructor; // Model name cannot be resolved from registry
}

// Access errors from bookshelf instance
const {
  NotFoundError,
  EmptyError, 
  NoRowsUpdatedError,
  NoRowsDeletedError,
  ModelNotResolvedError
} = bookshelf;

// Also available on Model and Collection constructors
const { NotFoundError: ModelNotFound } = bookshelf.Model;
const { EmptyError: CollectionEmpty } = bookshelf.Collection;

Usage Examples:

try {
  // This will throw NotFoundError if no user found
  const user = await new User({id: 999}).fetch({require: true});
} catch (error) {
  if (error instanceof bookshelf.NotFoundError) {
    console.log('User not found');
  }
}

try {
  // This will throw EmptyError if no users found  
  const users = await Users.forge().fetch({require: true});
} catch (error) {
  if (error instanceof bookshelf.EmptyError) {
    console.log('No users in collection');
  }
}

Types

// Core type definitions
interface Transaction {
  // Knex transaction object
  commit(): Promise<void>;
  rollback(): Promise<void>;
}

interface Relation {
  where(...args: any[]): Relation;
  query(callback: (qb: Knex.QueryBuilder) => void): Relation;
  through(Interim: string | ModelConstructor, throughForeignKey?: string, otherKey?: string): Relation;
  withPivot(...columns: string[]): Relation;
}

interface ModelConstructor {
  new(attributes?: object, options?: object): Model;
  forge(attributes?: object, options?: object): Model;
  extend(protoProps?: object, staticProps?: object): ModelConstructor;
}

interface CollectionConstructor {
  new(models?: Model[], options?: object): Collection;
  forge(models?: Model[], options?: object): Collection;
  extend(protoProps?: object, staticProps?: object): CollectionConstructor;
}