Registry / database / bookshelf-paranoia

bookshelf-paranoia

JSON →
library0.13.1jsnpmunverified

bookshelf-paranoia is a plugin for Bookshelf.js that provides a transparent soft-delete mechanism for database records. Instead of permanently removing rows when `destroy` is called on a model, it sets a `deleted_at` timestamp on the record, effectively marking it as deleted without losing the data. This allows for easier data recovery and maintains historical data integrity within the database. The package is currently at version 0.13.1. A crucial aspect of this package is its "unmaintained" status, as explicitly stated by the author, who only dedicates minimal time to small fixes at a slow pace. This implies an uncertain release cadence and potential for slow resolution of issues. Its primary differentiator lies in seamlessly integrating soft-delete logic directly into Bookshelf models and queries, automatically excluding soft-deleted records from standard `fetch` operations and eager loadings, while offering overrides for hard deletion or retrieval of deleted records. This transparent approach minimizes changes required in application logic when implementing soft deletes.

npm install bookshelf-paranoia
INSTALL
IMPORT
SIG · BOOKSHELF-PARANOIA
B
bookshelf-paranoia
databasejavascriptv0.13.1
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

plugin
bookshelf.plugin(require('bookshelf-paranoia'))
import Paranoia from 'bookshelf-paranoia'
This package is a Bookshelf plugin, intended for use with CommonJS `require()` and registered directly with a Bookshelf instance. It does not provide named or default ESM exports for direct import.

Demonstrates the installation, model configuration, and basic usage of `bookshelf-paranoia` including soft deletion, fetching deleted records, and performing hard deletes.

const Knex = require('knex'); const Bookshelf = require('bookshelf'); // Mock Knex setup for demonstration const knex = Knex({ client: 'sqlite3', connection: { filename: ':memory:' }, useNullAsDefault: true }); const bookshelf = Bookshelf(knex); // Add the plugin bookshelf.plugin(require('bookshelf-paranoia')); // Define a model with soft delete enabled const User = bookshelf.Model.extend({ tableName: 'users', softDelete: true, idAttribute: 'id' }); async function runExample() { try { // Create users table if it doesn't exist await knex.schema.hasTable('users').then(exists => { if (!exists) { return knex.schema.createTable('users', table => { table.increments('id').primary(); table.string('name'); table.timestamp('deleted_at'); // Default field for soft delete }); } }); // Insert a user const newUser = await User.forge({ name: 'Alice' }).save(); console.log('Created user:', newUser.toJSON()); // Soft delete the user await newUser.destroy(); console.log('Soft-deleted user.'); // Try to fetch the user (should return null as it's soft-deleted) const fetchedUser = await User.forge({ id: newUser.id }).fetch(); console.log('Fetched user after soft-delete (should be null):', fetchedUser ? fetchedUser.toJSON() : 'null'); // Fetch the user, including soft-deleted records const fetchedWithDeleted = await User.forge({ id: newUser.id }).fetch({ withDeleted: true }); console.log('Fetched user withDeleted: ', fetchedWithDeleted.toJSON()); console.log('Deleted at timestamp:', fetchedWithDeleted.get('deleted_at')); // Perform a hard delete (bypassing soft delete) const userToHardDelete = await User.forge({ name: 'Bob' }).save(); console.log('Created user for hard delete:', userToHardDelete.toJSON()); await userToHardDelete.destroy({ hardDelete: true }); console.log('Hard-deleted user.'); const fetchedHardDeleted = await User.forge({ id: userToHardDelete.id }).fetch({ withDeleted: true }); console.log('Fetched hard-deleted user (should be null):', fetchedHardDeleted ? fetchedHardDeleted.toJSON() : 'null'); } catch (error) { console.error('Error during example run:', error); } finally { await knex.destroy(); } } runExample();
Debug
Known issues
breakingThe package is explicitly marked as 'unmaintained' by its author. While small fixes might occur, active development, new features, or timely security patches are not expected. Consider forks or alternative solutions for critical projects.
fix
Evaluate the project's long-term viability for your application. Consider contributing to a fork or migrating to an actively maintained solution for soft deletes in Bookshelf.js or your ORM of choice.
affects: >=0.1.0
gotchaUnique constraints on database columns will still apply to soft-deleted rows by default. This can lead to errors when attempting to insert a new record with a value that already exists in a soft-deleted row, even though it's logically 'deleted'.
fix
Implement partial (or 'scoped') unique indexes at the database level where the uniqueness constraint only applies to records where `deleted_at` IS NULL. Alternatively, modify your application logic to check for soft-deleted conflicts before insertion, or consider unique constraints that include the `deleted_at` field.
affects: >=0.1.0
gotchaBy default, soft delete operations using `destroy()` on a Bookshelf model still emit 'destroying' and 'destroyed' events. This might be unexpected if event listeners are configured to only react to permanent data removal, potentially triggering unintended side effects.
fix
If this behavior is undesirable, you can disable event emission for soft deletes when configuring the plugin: `bookshelf.plugin(require('bookshelf-paranoia'), { events: false })` or disable specific events: `bookshelf.plugin(require('bookshelf-paranoia'), { events: { destroying: false } })`. Adjust your event listeners to account for soft deletions or only trigger on `hardDelete: true` scenarios.
affects: >=0.1.0
Errors
Common errors & fixes
SQLITE_CONSTRAINT: UNIQUE constraint failed: users.email
Attempted to insert a new record with a value for a unique column (e.g., 'email') that matches a value in a soft-deleted row, triggering a database-level unique constraint violation.
fix
Modify your database schema to use partial unique indexes. For PostgreSQL, `CREATE UNIQUE INDEX users_email_unique ON users (email) WHERE deleted_at IS NULL;`. For MySQL, this often requires a more complex multi-column unique key including `deleted_at` or application-level checks. Ensure your `deleted_at` column allows NULL values and defaults to NULL.
Upgrade
Version history
0.13.1latest on npm
Audit
Dependencies
bookshelfrequiredCore ORM library that this package extends as a plugin.
knexrequiredBookshelf's underlying query builder, indirectly required.
Agent activity
11 hits · last 30 days
node
10
OpenAI (training)
1
Resources
bookshelf-paranoia — npm install bookshelf-paranoia · libregistry