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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@dsavidge02/mongo-connector-ts

v2.0.1

Published

Basic Mongo Connector Singleton Instance

Readme

MongoDB Connector TypeScript

A robust, type-safe MongoDB connector library with a singleton pattern, comprehensive error handling, and modern async/await operations.

Installation

npm install @dsavidge02/mongo-connector-ts

Features

  • Singleton Pattern: Single connection instance across your application
  • Type-Safe: Full TypeScript support with generics
  • Comprehensive Error Handling: Custom error classes for different failure scenarios
  • Connection Management: Built-in retry logic with exponential backoff
  • Index Management: Easy-to-use methods for creating and managing indexes
  • Bulk Operations: Efficient multi-document operations
  • Query Enhancements: Powerful query options with limit, skip, and sort
  • Zero Logging: Silent by default, won't pollute your logs
  • Testing Utilities: Helper functions for testing with the singleton pattern

Quick Start

import { mongoConnector } from '@dsavidge02/mongo-connector-ts';

// Connect to MongoDB
await mongoConnector.connect('mongodb://localhost:27017', 'myDatabase');

// Create a document
interface User {
    name: string;
    email: string;
    age: number;
}

const user = await mongoConnector.createOne<User>('users', {
    name: 'Alice',
    email: '[email protected]',
    age: 30
});

// Query documents
const users = await mongoConnector.getMany<User>('users',
    { age: { $gte: 25 } },
    { limit: 10, sort: { name: 1 } }
);

// Close connection when done
await mongoConnector.close();

API Reference

Connection Management

connect(uri: string, dbName?: string, options?: ConnectOptions): Promise<void>

Connects to MongoDB with automatic retry logic.

// Basic connection
await mongoConnector.connect('mongodb://localhost:27017', 'mydb');

// With custom retry options
await mongoConnector.connect('mongodb://localhost:27017', 'mydb', {
    retry: {
        maxAttempts: 5,
        baseDelayMs: 200,
        maxDelayMs: 10000
    }
});

close(): Promise<void>

Closes the MongoDB connection and resets the connector state.

await mongoConnector.close();

setDB(dbName: string): void

Switches to a different database.

mongoConnector.setDB('anotherDatabase');

isConnected(): boolean

Checks if the connector is currently connected.

if (mongoConnector.isConnected()) {
    console.log('Connected to MongoDB');
}

CRUD Operations

createOne<T>(collectionName: string, document: T): Promise<WithId<T>>

Creates a single document and returns it with its generated _id.

const user = await mongoConnector.createOne<User>('users', {
    name: 'Bob',
    email: '[email protected]',
    age: 25
});
// user now has _id property

Throws: DuplicateKeyError if a unique index is violated.

getOne<T>(collectionName: string, filter: Filter<T>): Promise<WithId<T> | null>

Finds a single document matching the filter.

const user = await mongoConnector.getOne<User>('users', { email: '[email protected]' });
if (user) {
    console.log(user.name);
}

Returns: null if no document is found.

getMany<T>(collectionName: string, filter?: Filter<T>, options?: QueryOptions): Promise<WithId<T>[]>

Finds multiple documents with optional query options.

// Get all users
const allUsers = await mongoConnector.getMany<User>('users');

// Get users with filter
const adults = await mongoConnector.getMany<User>('users', { age: { $gte: 18 } });

// With query options
const topUsers = await mongoConnector.getMany<User>(
    'users',
    { active: true },
    { limit: 10, skip: 0, sort: { createdAt: -1 } }
);

updateOne<T>(collectionName: string, filter: Filter<T>, update: UpdateFilter<T>): Promise<WithId<T>>

Updates a single document and returns the updated document.

const updatedUser = await mongoConnector.updateOne<User>(
    'users',
    { email: '[email protected]' },
    { $set: { age: 31 } }
);

Throws: DocumentNotFoundError if no document matches the filter.

deleteOne<T>(collectionName: string, filter: Filter<T>): Promise<void>

Deletes a single document.

await mongoConnector.deleteOne<User>('users', { email: '[email protected]' });

Throws: DocumentNotFoundError if no document matches the filter.

Bulk Operations

createMany<T>(collectionName: string, documents: T[]): Promise<BulkCreateResult<T>>

Inserts multiple documents, continuing on error (unordered insert).

const result = await mongoConnector.createMany<User>('users', [
    { name: 'User1', email: '[email protected]', age: 20 },
    { name: 'User2', email: '[email protected]', age: 25 },
    { name: 'User3', email: '[email protected]', age: 30 }
]);

console.log(`Inserted: ${result.inserted.length}`);
console.log(`Failed: ${result.failed.length}`);

Returns: Object with inserted array and failed array. Throws: ValidationError if all documents fail to insert.

updateMany<T>(collectionName: string, filter: Filter<T>, update: UpdateFilter<T>): Promise<number>

Updates all documents matching the filter.

const modifiedCount = await mongoConnector.updateMany<User>(
    'users',
    { active: false },
    { $set: { status: 'inactive' } }
);
console.log(`Updated ${modifiedCount} documents`);

Returns: Number of documents modified.

deleteMany<T>(collectionName: string, filter: Filter<T>): Promise<number>

Deletes all documents matching the filter.

const deletedCount = await mongoConnector.deleteMany<User>(
    'users',
    { status: 'inactive' }
);

Returns: Number of documents deleted. Throws: ValidationError if filter is empty (safety check).

deleteAll<T>(collectionName: string): Promise<number>

Deletes all documents in a collection (explicit method to prevent accidents).

const deletedCount = await mongoConnector.deleteAll<User>('users');

Query Utilities

count<T>(collectionName: string, filter?: Filter<T>): Promise<number>

Counts documents matching the filter.

const totalUsers = await mongoConnector.count<User>('users');
const activeUsers = await mongoConnector.count<User>('users', { active: true });

exists<T>(collectionName: string, filter: Filter<T>): Promise<boolean>

Checks if any document matches the filter (more efficient than getOne).

const emailExists = await mongoConnector.exists<User>('users', {
    email: '[email protected]'
});

Index Management

ensureIndex<T>(collectionName: string, field: keyof T & string, options?: CreateIndexesOptions): Promise<string>

Creates an index on a field.

await mongoConnector.ensureIndex<User>('users', 'email');

ensureUniqueIndex<T>(collectionName: string, field: keyof T & string): Promise<string>

Creates a unique index on a field.

await mongoConnector.ensureUniqueIndex<User>('users', 'email');

ensureCompoundIndex<T>(collectionName: string, fields: (keyof T & string)[], options?: CreateIndexesOptions): Promise<string>

Creates a compound index on multiple fields.

await mongoConnector.ensureCompoundIndex<User>('users', ['email', 'name'], { unique: true });

listIndexes(collectionName: string): Promise<Document[]>

Lists all indexes on a collection.

const indexes = await mongoConnector.listIndexes('users');
console.log(indexes);

dropIndex(collectionName: string, indexName: string): Promise<void>

Drops an index from a collection.

await mongoConnector.dropIndex('users', 'email_1');

Error Handling

The library provides custom error classes for different scenarios:

ConnectionError

Thrown when connection to MongoDB fails.

import { ConnectionError } from '@dsavidge02/mongo-connector-ts';

try {
    await mongoConnector.connect('mongodb://invalid-uri:27017');
} catch (err) {
    if (err instanceof ConnectionError) {
        console.error('Failed to connect:', err.message);
        console.error('URI:', err.uri);
    }
}

ValidationError

Thrown when input validation fails.

import { ValidationError } from '@dsavidge02/mongo-connector-ts';

try {
    await mongoConnector.createMany('users', []); // Empty array
} catch (err) {
    if (err instanceof ValidationError) {
        console.error('Validation failed:', err.field);
    }
}

InvalidObjectIdError

Thrown when an invalid ObjectId string is provided.

import { InvalidObjectIdError } from '@dsavidge02/mongo-connector-ts';

try {
    await mongoConnector.getOne('users', { _id: 'not-valid-id' });
} catch (err) {
    if (err instanceof InvalidObjectIdError) {
        console.error('Invalid ID:', err.value);
    }
}

DuplicateKeyError

Thrown when a unique index constraint is violated.

import { DuplicateKeyError } from '@dsavidge02/mongo-connector-ts';

try {
    await mongoConnector.createOne('users', { email: '[email protected]' });
} catch (err) {
    if (err instanceof DuplicateKeyError) {
        console.error(`Duplicate ${err.field} in ${err.collection}`);
    }
}

DocumentNotFoundError

Thrown when updateOne or deleteOne cannot find the target document.

import { DocumentNotFoundError } from '@dsavidge02/mongo-connector-ts';

try {
    await mongoConnector.updateOne('users', { _id: 'nonexistent' }, { $set: { name: 'X' } });
} catch (err) {
    if (err instanceof DocumentNotFoundError) {
        console.error(`Not found in ${err.collection}: ${err.id}`);
    }
}

Testing

The library provides testing utilities to work with the singleton pattern:

import { resetMongoConnector, createTestConnector } from '@dsavidge02/mongo-connector-ts/testing';

describe('My Tests', () => {
    beforeEach(() => {
        // Reset singleton between tests
        resetMongoConnector();
    });

    it('should work with independent connector', () => {
        // Create independent test instance
        const testConnector = createTestConnector();
        // Use testConnector in your tests
    });
});

TypeScript Types

All operations support full TypeScript generics:

interface Product {
    name: string;
    price: number;
    category: string;
    inStock: boolean;
}

// Type-safe operations
const product = await mongoConnector.createOne<Product>('products', {
    name: 'Widget',
    price: 29.99,
    category: 'Tools',
    inStock: true
});

// product._id is typed as ObjectId
// product.name is typed as string

Migration from v1.x

Breaking Changes in v2.0.0

  1. createOne signature changed:

    • Before: createOne(collection, doc, uniqueFields)
    • After: createOne(collection, doc)
    • Use ensureUniqueIndex() to create unique indexes instead
  2. createOne return type changed:

    • Before: Returns WithId<T> | null
    • After: Returns WithId<T> (throws on error)
  3. getCollectionArray removed:

    • Use getMany() instead
  4. No more console logging:

    • Library is silent; handle errors with try-catch

Migration Example

// v1.x
const user = await mongoConnector.createOne('users',
    { email: '[email protected]', name: 'Test' },
    ['email'] // uniqueFields parameter
);
if (!user) {
    console.error('Failed to create user');
}

// v2.0.0
// Setup (once, during app initialization)
await mongoConnector.ensureUniqueIndex<User>('users', 'email');

// Usage
try {
    const user = await mongoConnector.createOne('users',
        { email: '[email protected]', name: 'Test' }
    );
    // user is guaranteed to exist here
} catch (err) {
    if (err instanceof DuplicateKeyError) {
        console.error('Email already exists');
    }
}

Future Work

The following features are planned for post-v2.0.0 releases:

Phase 9: Aggregation Support

  • Type-safe aggregation pipeline execution
  • Support for complex MongoDB aggregation operations
  • Generic typing for input and output document types

Phase 10: Transaction Support

  • Multi-document atomic operations
  • Automatic commit/abort handling
  • Note: Requires MongoDB replica set configuration

These features will be added in subsequent minor or major version releases based on user demand and project priorities.

License

MIT

Author

Daniel Savidge

Repository

https://github.com/dsavidge02/mongo-connector