@flickerstop/jrmongo
v2.0.0
Published
A lightweight MongoDB wrapper for Node.js with simplified operations and connection management
Maintainers
Readme
JrMongo
A lightweight MongoDB wrapper for Node.js that simplifies database operations with an intuitive API and automatic connection management.
Features
- Simple API — Easy-to-use methods for all common MongoDB operations
- Auto Connection — Connects on first use, reuses connections automatically
- Silent by Default — No console output unless you enable verbose mode
- Environment Variables — Built-in
.envsupport via dotenv - Connection Options — Pass-through options to MongoClient (pool size, TLS, timeouts)
- TypeScript Ready — Includes comprehensive type definitions
- Dual Format — Works with both ESM (
import) and CommonJS (require) - ObjectId Export — Re-exports MongoDB's
ObjectIdfor convenience
Installation
npm install @flickerstop/jrmongoQuick Start
- Create a
.envfile in your project root:
MONGODB_URL=mongodb://localhost:27017- Use JrMongo in your application:
import { JrMongo } from '@flickerstop/jrmongo';
const db = JrMongo.db('myapp');
// Insert
await db.add('users', { name: 'Alice', email: '[email protected]' });
// Find
const users = await db.find('users', { name: 'Alice' });
// Update
await db.update('users', { name: 'Alice' }, { email: '[email protected]' });
// Delete
await db.deleteOne('users', { name: 'Alice' });
// Close when done
await db.close();API Reference
JrMongo.db(dbName, dbURL?, options?)
Creates a new database connection instance.
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| dbName | string | — | Name of the database |
| dbURL | string | process.env.MONGODB_URL | MongoDB connection URL |
| options | object | {} | Options passed through to MongoClient |
// Basic
const db = JrMongo.db('myapp');
// With custom URL
const db = JrMongo.db('myapp', 'mongodb://localhost:27017');
// With connection options
const db = JrMongo.db('myapp', 'mongodb://localhost:27017', {
maxPoolSize: 20,
connectTimeoutMS: 5000
});JrMongo.configure(options)
Configures global settings.
JrMongo.configure({ verbose: true }); // Enable connection loggingJrMongo.isReady(dbName?)
Check if a database connection is established.
JrMongo.isReady('myapp'); // Check specific DB
JrMongo.isReady(); // Check if any connection existsJrMongo.close(dbName?)
Close a specific connection or all connections.
await JrMongo.close('myapp'); // Close one
await JrMongo.close(); // Close allFind Operations
find(tableName, searchFor?, options?)
Find documents matching criteria with optional sort, skip, limit, and projection.
const users = await db.find('users', { age: { $gte: 18 } });
// With pagination and sorting
const page = await db.find('users', {}, {
sort: { createdAt: -1 },
skip: 20,
limit: 10,
projection: { name: 1, email: 1 }
});findOne(tableName, searchFor?, projection?)
Find a single document. Returns null if not found.
const user = await db.findOne('users', { email: '[email protected]' });findFirst(tableName, searchFor?, projection?)
Alias for findOne().
findAll(tableName, projection?)
Find all documents in a collection.
const allUsers = await db.findAll('users', { name: 1, email: 1 });findLimit(tableName, searchFor, limit)
Find documents with a limit.
const top10 = await db.findLimit('users', {}, 10);findLimitEnd(tableName, searchFor, limit)
Find the last N documents (sorted by natural insertion order, newest first).
const latest = await db.findLimitEnd('logs', {}, 5);findText(tableName, textToSearchFor)
Perform text search (requires a text index on the collection).
const match = await db.findText('articles', 'mongodb tutorial');Insert Operations
add(tableName, newObject)
Insert a single document.
const result = await db.add('users', { name: 'Alice', age: 30 });
console.log(result.insertedId);addMany(tableName, arrayOfNewObjects)
Insert multiple documents.
const result = await db.addMany('users', [
{ name: 'Bob', age: 25 },
{ name: 'Carol', age: 35 }
]);
console.log(result.insertedCount); // 2Update Operations
update(tableName, searchFor, updateTo, upsert?)
Update a single document using $set.
await db.update('users', { name: 'Alice' }, { age: 31 });
// With upsert (create if not found)
await db.update('users', { name: 'Eve' }, { name: 'Eve', age: 22 }, true);updateMany(tableName, searchFor, updateTo)
Update multiple documents using $set.
await db.updateMany('users', { role: 'guest' }, { active: false });updateParts(tableName, searchFor, updateTo, upsert?)
Update nested fields without overwriting sibling fields. Uses dot-notation flattening internally.
// Only updates address.city, leaves address.state and address.zip intact
await db.updateParts('users', { name: 'Alice' }, {
address: { city: 'New York' }
});findOneAndUpdate(tableName, searchFor, updateTo, options?)
Atomically find and update a document, returning the document.
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| upsert | boolean | false | Create if not found |
| returnNew | boolean | true | Return updated doc (true) or original (false) |
| projection | object | — | Fields to include/exclude |
const user = await db.findOneAndUpdate('users',
{ name: 'Alice' },
{ loginCount: 5 },
{ returnNew: true }
);push(tableName, searchFor, valueToPush, upsert?)
Push a value onto an array field using $push.
await db.push('users', { name: 'Alice' }, { tags: 'admin' });bulkWrite(tableName, data)
Perform bulk write operations.
await db.bulkWrite('users', [
{ insertOne: { document: { name: 'David', age: 28 } } },
{ updateOne: { filter: { name: 'Alice' }, update: { $set: { age: 32 } } } },
{ deleteOne: { filter: { name: 'Bob' } } }
]);Delete Operations
deleteOne(tableName, searchFor)
Delete a single document.
await db.deleteOne('users', { name: 'Bob' });deleteMany(tableName, searchFor?)
Delete multiple documents. Pass empty or no filter to delete all.
await db.deleteMany('users', { active: false });
await db.deleteMany('temp_data'); // delete allfindOneAndDelete(tableName, searchFor, options?)
Atomically find and delete a document, returning the deleted document.
| Option | Type | Description |
|--------|------|-------------|
| projection | object | Fields to include/exclude |
| sort | object | Sort to determine which document to delete |
const deleted = await db.findOneAndDelete('queue', { status: 'pending' });Aggregation
aggregate(tableName, pipeline)
Run an aggregation pipeline.
const stats = await db.aggregate('orders', [
{ $match: { status: 'completed' } },
{ $group: { _id: '$product', total: { $sum: '$amount' } } },
{ $sort: { total: -1 } }
]);Count & Utility
count(tableName, searchFor?)
Count documents matching the filter.
const total = await db.count('users');
const admins = await db.count('users', { role: 'admin' });getTableNames()
Get all collection names in the database.
const collections = await db.getTableNames();close()
Close this database connection.
await db.close();Index Management
createIndex(tableName, indexSpec, options?)
Create an index on a collection.
await db.createIndex('users', { email: 1 }, { unique: true });
await db.createIndex('articles', { title: 'text', body: 'text' });createIndexes(tableName, indexSpecs)
Create multiple indexes at once.
await db.createIndexes('users', [
{ key: { email: 1 }, unique: true },
{ key: { createdAt: -1 } }
]);dropIndex(tableName, indexName)
Drop a specific index.
await db.dropIndex('users', 'email_1');dropIndexes(tableName)
Drop all indexes (except _id).
listIndexes(tableName)
List all indexes on a collection.
const indexes = await db.listIndexes('users');Collection Management
createCollection(collectionName, options?)
Create a new collection.
await db.createCollection('logs', { capped: true, size: 1048576 });dropCollection(collectionName)
Drop a collection.
await db.dropCollection('old_logs');ObjectId
JrMongo re-exports MongoDB's ObjectId for convenience, so you don't need to install or import mongodb separately:
import { JrMongo, ObjectId } from '@flickerstop/jrmongo';
const user = await db.findOne('users', { _id: new ObjectId('507f1f77bcf86cd799439011') });Environment Variables
| Variable | Required | Description |
|----------|----------|-------------|
| MONGODB_URL | Yes (unless passed to db()) | MongoDB connection string |
Example .env file:
MONGODB_URL=mongodb://localhost:27017
# or for MongoDB Atlas:
MONGODB_URL=mongodb+srv://username:[email protected]Error Handling
All methods return promises. Use try/catch for error handling:
try {
await db.add('users', { name: 'Alice' });
} catch (error) {
console.error('Database operation failed:', error);
}Input validation throws immediately for invalid arguments:
try {
await db.find(''); // Empty collection name
} catch (error) {
// "JrMongo: tableName must be a non-empty string"
}Connection Management
- Connections are established lazily on first operation
- Connections are reused across all operations on the same database
- Multiple database connections can coexist simultaneously
- Call
db.close()orJrMongo.close()to clean up
TypeScript Support
JrMongo includes comprehensive TypeScript definitions:
import { JrMongo, ObjectId } from '@flickerstop/jrmongo';
interface User {
_id?: ObjectId;
name: string;
email: string;
age: number;
}
const db = JrMongo.db('myapp');
const user = await db.findOne<User>('users', { name: 'Alice' });
const users = await db.find<User>('users', {}, { sort: { name: 1 }, limit: 10 });Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT License - see LICENSE file for details.
