npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

mongomod

v2.1.5

Published

**A powerful MongoDB model-based library for Node.js with TypeScript support**

Readme

MongoMod

A powerful MongoDB model-based library for Node.js with TypeScript support

MongoMod is a feature-rich MongoDB ODM (Object Document Mapper) that provides an intuitive, model-based approach to working with MongoDB databases. It combines the flexibility of MongoDB with the structure and safety of schema validation, custom methods, and event-driven programming.

🚀 Features

  • Model-Based Architecture: Define reusable models with schema validation
  • Schema Validation: Built-in validation using the validno library
  • Custom Methods: Extend models with your own custom functionality
  • Event System: Subscribe to model lifecycle events (create, update, delete)
  • Full MongoDB Support: Complete CRUD operations, aggregation, indexing, and more
  • TypeScript Support: Full TypeScript definitions and type safety
  • Connection Management: Robust connection handling with timeout and error management
  • Static & Instance Methods: Flexible API for different use cases

📦 Installation

npm i mongomod

🔧 Quick Start

1. Basic Setup

import mongomod from 'mongomod';

// Create connection
const db = new mongomod.Connection({
    link: 'your-mongo-host:27017',
    login: 'username',
    password: 'password',
    dbName: 'your-database',
    srv: false // Set to true for MongoDB Atlas
});

// Connect to database
await db.connect();

2. Define a Schema

import { MongoSchema } from 'mongomod';

const userSchema = new MongoSchema({
    name: { type: String, required: true },
    email: { type: String, required: true },
    age: { type: Number, required: false },
    createdAt: { type: Date, required: false }
});

3. Create a Model

// Define custom methods
const customMethods = {
    getFullInfo() {
        return `${this.data().name} (${this.data().email})`;
    },
    
    isAdult() {
        return this.data().age >= 18;
    }
};

// Create the model
const User = mongomod.createModel({
    db: db,
    collection: 'users',
    schema: userSchema,
    customs: customMethods
});

4. Use the Model

// Create and save a new user
const user = new User().init({
    name: 'John Doe',
    email: '[email protected]',
    age: 25
});

await user.save(true); // true = insert if not exists

// Use custom methods
console.log(user.getFullInfo()); // "John Doe ([email protected])"
console.log(user.isAdult()); // true

// Static methods for querying
const foundUser = await User.findOne({
    filter: { email: '[email protected]' }
});

const allUsers = await User.findMany({
    filter: { age: { $gte: 18 } }
});

📚 Core Components

MongoConnection

Handles database connections with robust error handling and timeout management.

const connection = new mongomod.Connection({
    link: 'localhost:27017',
    login: 'username',
    password: 'password',
    dbName: 'myapp',
    srv: false
});

// Connect with optional callback and timeout
await connection.connect(() => {
    console.log('Connected successfully!');
}, 10000); // 10 second timeout

// Disconnect
await connection.disconnect();

MongoSchema

Provides data validation and structure definition using the validno library.

const schema = new MongoSchema({
    title: { type: String, required: true },
    content: { type: String },
    tags: { type: Array },
    published: { type: Boolean },
    publishedAt: { type: Date }
}, {
    strict: true // Enforce strict validation
});

// Validate data
const isValid = schema.validate({
    title: 'My Post',
    content: 'Post content...'
});

MongoController

Low-level database operations controller. Usually used internally by models, but can be used directly.

const controller = new mongomod.Controller(db, 'posts');

// Direct database operations
const result = await controller.findMany({
    filter: { published: true },
    sort: { publishedAt: -1 },
    limit: 10
});

MongoModel

The main model class that combines schema validation, custom methods, and database operations.

// Or use the factory method
const Post = mongomod.createModel({
    db: connection,
    collection: 'posts',
    schema: postSchema,
    customs: {
        publish() {
            this.set({ 
                published: true, 
                publishedAt: new Date() 
            });
            return this.save();
        }
    }
});

🔍 Model Methods

Instance Methods

const user = new User();

// Initialize with data
user.init({ name: 'Alice', age: 30 });

// Set/update data
user.set({ age: 31 });

// Save to database
await user.save(); // Update existing
await user.save(true); // Insert if not exists

// Get data from database
await user.get({ name: 'Alice' });

// Delete from database
await user.delete();

// Validation
const isValid = user.validate();

// Data access
const userData = user.data();
const filteredData = user.dataFiltered(['name', 'email']);

// String representation
const jsonString = user.toString();

Static Methods (Query Methods)

// Find operations
const user = await User.findOne({
    filter: { email: '[email protected]' }
});

const users = await User.findMany({
    filter: { age: { $gte: 18 } },
    sort: { name: 1 },
    limit: 50
});

// Insert operations
const result = await User.insertOne({
    name: 'Bob', email: '[email protected]', age: 25
});

const results = await User.insertMany({
    data: [
        { name: 'Carol', email: '[email protected]', age: 28 },
        { name: 'Dave', email: '[email protected]', age: 32 }
    ]
});

// Update operations
await User.updateOne({
    filter: { name: 'Bob' },
    update: { $set: { age: 26 } }
});

await User.updateMany({
    filter: { age: { $lt: 18 } },
    update: { $set: { status: 'minor' } }
});

// Delete operations
await User.deleteOne({
    filter: { email: '[email protected]' }
});

await User.deleteMany({
    filter: { status: 'inactive' }
});

// Aggregation
const results = await User.aggregate([
    { $match: { age: { $gte: 18 } } },
    { $group: { _id: '$status', count: { $sum: 1 } } }
]);

// Count documents
const count = await User.count({
    filter: { status: 'active' }
});

// Get distinct values
const distinctAges = await User.distinct({
    field: 'age',
    filter: { status: 'active' }
});

// Bulk operations
await User.bulkWrite([
    { insertOne: { document: { name: 'Eve', age: 22 } } },
    { updateOne: { filter: { name: 'Alice' }, update: { $inc: { age: 1 } } } },
    { deleteOne: { filter: { status: 'deleted' } } }
]);

🎯 Event System

Subscribe to model lifecycle events to trigger custom logic:

// Subscribe to events
User.subscribe('created', (newData, oldData) => {
    console.log('New user created:', newData);
    // Send welcome email, update analytics, etc.
});

User.subscribe('updated', (newData, oldData) => {
    console.log('User updated:', { old: oldData, new: newData });
    // Log changes, notify users, etc.
});

User.subscribe('deleted', (deletedData) => {
    console.log('User deleted:', deletedData);
    // Cleanup related data, send notifications, etc.
});

// Events are automatically triggered during operations
const user = new User().init({ name: 'Test User', age: 25 });
await user.insert(); // Triggers 'created' event

user.set({ age: 26 });
await user.save(); // Triggers 'updated' event

await user.delete(); // Triggers 'deleted' event

🛠️ Advanced Usage

Complex Schema Validation

For more information about advanced schema validation, see the validno package on NPM.

Model Inheritance and Extension

// Base model with common functionality
const baseCustoms = {
    // Add timestamps
    touch() {
        this.set({ updatedAt: new Date() });
        return this;
    },
    
    // Soft delete
    softDelete() {
        this.set({ deletedAt: new Date(), active: false });
        return this.save();
    }
};

// Create specialized models
const User = mongomod.createModel({
    db: connection,
    collection: 'users',
    schema: userSchema,
    customs: {
        ...baseCustoms,
        authenticate(password) {
            // User-specific authentication logic
            return bcrypt.compare(password, this.data().passwordHash);
        }
    }
});

const Product = mongomod.createModel({
    db: connection,
    collection: 'products',
    schema: productSchema,
    customs: {
        ...baseCustoms,
        applyDiscount(percentage) {
            const currentPrice = this.data().price;
            const newPrice = currentPrice * (1 - percentage / 100);
            this.set({ price: newPrice });
            return this.save();
        }
    }
});

🔒 Error Handling

MongoMod provides specific error types for different scenarios:

import { 
    MmConnectionError, 
    MmValidationError, 
    MmOperationError, 
    MmControllerError 
} from 'mongomod';

try {
    await db.connect();
} catch (error) {
    if (error instanceof MmConnectionError) {
        console.error('Connection failed:', error.message);
    }
}

try {
    const user = new User().init({ name: 'Test' }); // Missing required field
} catch (error) {
    if (error instanceof MmValidationError) {
        console.error('Validation failed:', error.message);
    }
}

⚠️ Version 2.0+ Breaking Changes

IMPORTANT: Version 2.0.0 introduces breaking changes and is NOT backward compatible with versions prior to 2.0.0.

Migration Guide

  • Update import statements to use ES modules
  • Review schema definitions for new validation syntax
  • Update custom method definitions to use the new binding system
  • Check event subscriber syntax for any changes

🔗 Links