# mongo-base-crud

> Class to handler access and handler database

Latest version **0.5.1** (published 2026-08-15) · Apache-2.0 license · 0 weekly downloads

## Install

```sh
npm install mongo-base-crud
pnpm add mongo-base-crud
yarn add mongo-base-crud
bun add mongo-base-crud
```

## Health

**Score 70/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; recently updated; high maintenance score; high quality score.

Warnings: low downloads; pre 1.0.

## Facts

| | |
|---|---|
| Version | 0.5.1 |
| Published | 2026-08-15 |
| First published | 2024-05-21 |
| Weekly downloads | 0 |
| License | Apache-2.0 |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 11 |
| Unpacked size | 64.2 KB |
| Known vulnerabilities | 0 (+2 in 2 direct dependencies) |
| Install scripts | no |
| GitHub stars | 1 |
| Author | Renato Miawaki |
| Maintainers | reytuty |
| Keywords | mongo, crud, simple, typescript, auto-create |

## Links

- npm: https://www.npmjs.com/package/mongo-base-crud
- Repository: https://github.com/reytuty/mongo-base-crud
- Homepage: https://github.com/reytuty/mongo-base-crud#readme
- Issues: https://github.com/reytuty/mongo-base-crud/issues
- npm.io page: https://npm.io/package/mongo-base-crud

## Dependencies (11)

- [md5](https://npm.io/package/md5.md) ^2.3.0
- [crypto](https://npm.io/package/crypto.md) ^1.0.1
- [dotenv](https://npm.io/package/dotenv.md) ^16.4.5
- [vitest](https://npm.io/package/vitest.md) ^1.6.0
- [mongoose](https://npm.io/package/mongoose.md) ^8.4.0
- [@types/md5](https://npm.io/package/@types/md5.md) ^2.3.5
- [typescript](https://npm.io/package/typescript.md) ^5.0.4
- [@types/jest](https://npm.io/package/@types/jest.md) ^29.5.1
- [@faker-js/faker](https://npm.io/package/@faker-js/faker.md) ^8.4.1
- [vite-tsconfig-paths](https://npm.io/package/vite-tsconfig-paths.md) ^4.3.2
- [typescript-singleton](https://npm.io/package/typescript-singleton.md) ^0.1.3

## Alternatives

- [angular-pipes](https://npm.io/package/angular-pipes.md) — 5.6K weekly downloads
- [@ng-web-apis/midi](https://npm.io/package/@ng-web-apis/midi.md) — 2.6K weekly downloads
- [happn-3](https://npm.io/package/happn-3.md) — 1.6K weekly downloads
- [@opensip-cli/lang-go](https://npm.io/package/@opensip-cli/lang-go.md) — 1.2K weekly downloads
- [mongoose-typescript](https://npm.io/package/mongoose-typescript.md) — 85 weekly downloads

## Recent versions

- 0.5.1 (latest) — 2026-08-15
- 0.5.0 — 2026-08-15
- 0.4.6 — 2026-07-30
- 0.4.5 — 2026-07-30
- 0.4.4 — 2026-05-29
- 0.4.3 — 2026-05-29
- 0.4.1 — 2025-07-18
- 0.4.0 — 2025-04-22
- 0.3.4 — 2025-04-01
- 0.3.3 — 2025-03-26
- 0.3.2 — 2024-12-03
- 0.3.1 — 2024-12-02
- 0.3.0 — 2024-10-30
- 0.2.1 — 2024-10-07
- 0.2.0 — 2024-10-07
- … 10 more at https://npm.io/package/mongo-base-crud/versions

## README

# 🧩 mongo-base-crud

**TypeScript library to simplify CRUD operations with MongoDB.**

Built on top of [Mongoose](https://mongoosejs.com/), designed for whitelabel/multi-tenant projects, with support for multiple databases, dynamic aliases, and the Singleton pattern.

---

## ✨ Features

- 🔌 Simple Mongo connection with connection pooling (per-database Singleton)
- 🧬 Flexible schema (no strict typing at the DB layer) with automatic `_id ↔ id` mapping
- 🏢 Multi-tenant / whitelabel friendly (prefixes, per-alias databases)
- 🔁 Full CRUD: `save`, `update`, `partialUpdate`, `find`, `findAll`, `getById`, `delete`
- 📦 **Batch operations**: `saveMany`, `updateMany`, `deleteMany` (single-roundtrip `bulkWrite`)
- 🧮 `aggregate` helper with `allowDiskUse: true` by default
- 🚀 `find` / `findAll` also run with `allowDiskUse: true` by default (no more sort-memory errors on large datasets)
- 🧠 Automatic `createdAt` / `updatedAt` handling when those fields exist in your payload

---

## 📦 Installation

```bash
npm install mongo-base-crud
```

---

## ⚙️ Configuration

Create a `.env` file:

```env
MONGO_URL="mongodb://admin:admin@localhost:27017"
MONGO_DB=test
MONGO_PREFIX_NAME=test_
MONGO_DISABLE_PLURAL=true
```

| Variable | Description |
|---|---|
| `MONGO_URL` | MongoDB connection URL |
| `MONGO_DB` | Base database name |
| `MONGO_PREFIX_NAME` | Prefix for multi-tenant / whitelabel setups |
| `MONGO_DISABLE_PLURAL` | *(optional)* if `true`, disables Mongoose's automatic pluralization of collection names |

### Overriding config programmatically

You can bypass the env vars by passing a `MongoConfig` directly:

```ts
await BaseCrud.getInstance("exact_collection_name", "my_db", {}, 1, {
  fullUrl: "mongodb://localhost:27017",
  disablePlural: true,
});
```

---

## 🧠 `getInstance` vs `.instance()`

| Method | When to use |
|---|---|
| `BaseCrud.getInstance(...)` | Quick / generic usage. Returns a global Singleton keyed by `dbName_collectionName`. |
| `YourRepository.instance(alias)` | Recommended for whitelabel setups. Creates one Singleton per alias, using a custom key (e.g. `UserRepo_acme`). |

Both are backed by [`typescript-singleton`](https://www.npmjs.com/package/typescript-singleton), so repeated calls return the same instance and reuse the same Mongo connection.

---

## 🚀 Quick Start

### Generic usage

```ts
import { BaseCrud } from "mongo-base-crud";

const users = BaseCrud.getInstance<{ id: string; name: string }>(
  "users",
  "clinic_acme",
  { name: 1 }, // indexes
);

const { id } = await users.save({ name: "John" });
const john = await users.getById(id);
```

### Recommended: extend `BaseCrud` per entity

```ts
import { Singleton } from "typescript-singleton";
import { BaseCrud } from "mongo-base-crud";

interface User {
  id: string;
  name: string;
}

export class UserRepository extends BaseCrud<User> {
  public static instance(clinicAlias: string): UserRepository {
    const dbName = `clinic_${clinicAlias}`;
    return Singleton.getInstance<UserRepository>(
      `UserRepo_${clinicAlias}`,
      UserRepository,
      "users",
      dbName,
      { name: 1 },
    );
  }

  constructor(collection = "users", dbName = "default", indexes = {}) {
    super(collection, dbName, indexes);
  }
}

// usage
const repo = UserRepository.instance("acme");
await repo.save({ name: "Mary" });
```

---

## 📚 API Reference

All methods below are exposed on any `BaseCrud<T>` instance.

### Single-document operations

#### `save(data): Promise<DocumentWithId>`

Creates a new document, or replaces an existing one when `id` is provided (upsert).
Automatically refreshes `updatedAt` / `createdAt` if those fields exist on the payload.

```ts
await repo.save({ name: "John" });                    // insert with generated UUID
await repo.save({ id: "my-custom-id", name: "Mary" }); // upsert with custom id
```

#### `update(data): Promise<DocumentWithId>`

Fully replaces the document matched by `data.id`. Refreshes `updatedAt` when present.

```ts
await repo.update({ id: "abc", name: "New Name" });
```

#### `partialUpdate(id, data): Promise<DocumentWithId>`

Updates only the provided fields (uses dot-notation under the hood).

```ts
await repo.partialUpdate("abc", { name: "New Name" });
```

#### `getById(id): Promise<T | null>`

Retrieves a single document by its `id`.

#### `delete(id): Promise<{ success: true }>`

Deletes a document by its `id`.

---

### Batch operations

All batch methods use MongoDB's `bulkWrite` with `ordered: false` — a single roundtrip that keeps going even if individual documents fail.

#### `saveMany(data): Promise<DocumentWithId[]>`

Upserts an array of documents. Items with `id` are updated; items without get a generated UUID.
Also refreshes `updatedAt` / `createdAt` per item, just like `save`.

```ts
const results = await repo.saveMany([
  { name: "Alice" },                    // new
  { id: "existing-id", name: "Bob" },   // upsert
]);
// results: [{ id: "..." }, { id: "existing-id" }]
```

#### `updateMany(data): Promise<DocumentWithId[]>`

Fully updates (upserts) each document by its `id`.

```ts
await repo.updateMany([
  { id: "a", name: "Alice v2" },
  { id: "b", name: "Bob v2" },
]);
```

#### `deleteMany(ids): Promise<void>`

Deletes all documents whose `id` is in the provided list.

```ts
await repo.deleteMany(["a", "b", "c"]);
```

---

### Querying

#### `find(filter?, select?, skip?, limit?, orderBy?, direction?, searchValue?, searchFields?): Promise<List<T>>`

Filtered, paginated search with optional sorting and multi-field text search.
Runs with `allowDiskUse: true` by default to avoid the 100MB sort memory limit.

```ts
const page = await repo.find(
  { active: true },   // filter
  { name: 1 },        // select (projection)
  0,                  // skip
  20,                 // limit
  "name",             // orderBy
  "asc",              // direction
  "jo",               // searchValue
  ["name", "email"],  // searchFields
);
// page: { total, skipped, limited, list: T[] }
```

#### `findAll(filter?, select?, orderBy?, direction?, searchValue?, searchFields?): Promise<T[]>`

Same as `find`, but returns every match with no pagination. Also uses `allowDiskUse: true`.

---

### Aggregation

#### `aggregate(pipeline, options?): Promise<T>`

Runs an aggregation pipeline. `options` defaults to `{ allowDiskUse: true }`.

```ts
const result = await repo.aggregate([
  { $group: { _id: "$details.name", count: { $sum: 1 } } },
  { $project: { _id: 0, name: "$_id", count: 1 } },
]);
```

---

## 📐 Types

```ts
type DocumentWithId = { id: string };

type Offset = { skip: number; limit: number };

type List<T> = {
  total: number;
  skipped: number;
  limited: number;
  list: T[];
};
```

---

## 📌 Requirements

- Node.js >= 14
- MongoDB >= 4.x
- TypeScript >= 5.x

---

## ✅ Testing

Example with [Vitest](https://vitest.dev):

```ts
import { describe, it, expect } from "vitest";
import { UserRepository } from "./UserRepository";

describe("UserRepository", () => {
  it("should save a new document", async () => {
    const result = await UserRepository.instance("acme").save({ name: "Test" });
    expect(result.id).toBeDefined();
  });

  it("should save many documents in one roundtrip", async () => {
    const results = await UserRepository.instance("acme").saveMany([
      { name: "A" },
      { name: "B" },
    ]);
    expect(results).toHaveLength(2);
  });
});
```

Run:

```bash
npm test
```

---

## 🤝 Contributing

Pull requests are welcome! Suggestions, usage examples, and improvements are greatly appreciated.

---

## 📝 License

Apache-2.0 © IDress — Renato Miawaki

---
_Source: https://npm.io/package/mongo-base-crud · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
