@occupop/lib-mongo
v5.0.0
Published
This package is intended to use with `@occupop/lib-container` being a wrapper for basic MongoDB operations... providing factory for MongoClient, collection getter and repositories.
Maintainers
Keywords
Readme
Package @occupop/lib-mongo
This package is intended to use with @occupop/lib-container
being a wrapper for basic MongoDB operations...
providing factory for MongoClient, collection getter and repositories.
This implementation refers to https://www.mongodb.com/docs/drivers/node/current/fundamentals/! Check their docs for detailed/advanced usage.
NPM registry token required!
Install
# Yarn
yarn add @occupop/lib-mongo
# NPM
npm install @occupop/lib-mongo
# Bun
bun add @occupop/lib-mongoCompatibility
| | 5.x |
|---|---|
| MongoDB Node.js driver | mongodb 7 (^7.6.0), a dependency of this package |
| Node.js | 20.19 or later (the driver's engines.node) |
| MongoDB server | 4.4 or later (the driver's minimum; its maximum is 9.0) |
| Bun | 1.4.0 or later (see "5.0.0 breaking changes") |
| TypeScript | 5.x and 6.x (peer range ^5 \|\| ^6.0.0) |
The driver ships its own type declarations; @types/mongodb is not needed.
5.0.0 breaking changes
5.0.0 moves from mongodb 6 (^6.9.0) to mongodb 7 (^7.6.0). Every export keeps its name,
parameters and defaults: makeMongoClient (reads DB_URI), makeGetMongoCollection (reads
DB_NAME, default main), makeBaseRepository and the BaseRepository type. What changes:
- Driver 7 types in the public API.
MongoClient,Collection,Filter, the cursors and the results that this package returns are the driver 7 types. If your project also depends onmongodbdirectly, use the same range (^7.6.0) so that one copy of the driver is installed and the types match. findandfindOneoptions are typedFindOptions, which is not generic in driver 7. They were typedFindOptions<Model>. Code that writesFindOptions<Something>fails with TS2315 ("Type 'FindOptions' is not generic"); drop the type argument.- Node.js 20.19 or later, the driver's
engines.node. - MongoDB server 4.4 or later. Driver 7 does not connect to older servers.
- Bun 1.4.0 or later. The driver depends on
bson^7.2.0. Frombson7.3.0, loading the module callsv8.startupSnapshot.isBuildingSnapshot(), which every Bun 1.3.x rejects withNotImplementedError: node:v8 isBuildingSnapshot is not yet implemented in Bun. Bun 1.4.0 and later load it.
Env Setup
ENV variables required and some common values
DB_URI=mongodb://root:secret@localhost
DB_NAME=main
DB_URI=mongodb+srv://AwesomeUsrNme:s&crt^p@[email protected]
DB_NAME=ms-awesomeRegister
import {
makeMongoClient, makeGetMongoCollection
} from '@occupop/lib-mongo'
//... all other imports omited...
export const container = createTypedContainer({
// ...
// Top-level
mongoClient: { asFunction: makeMongoClient, singleton: true },
getMongoCollection: { asFunction: makeGetMongoCollection, singleton: true },
makeBaseRepository: { asValue: makeBaseRepository },
// Repositories
fooRepository: { asFunction: makeFooRepository, singleton: true },
barRepository: { asFunction: makeBarRepository, singleton: true },
// ...
})Usage (starting client)
// server.ts
import { container } from '.container'
const { mongoClient } = container.cradle
await mongoClient.connect()
console.log('Mongo connected')
// ...Usage (repository factory)
// app/foo.ts
export type Foo = {
uuid: string
title: string
age: number
createdAt: Date
}// data/foo-repository.ts
import type { Deps } from '.container'
import type { Foo } from './app/foo'
export function makeFooRepository({ getMongoCollection, makeBaseRepository }: Deps) {
const collection = getMongoCollection<Foo>('foo')
return makeBaseRepository(collection)
}Note: passing Foo type/entity to the generic collection getter is optional,
but will allow IDE type hint on finds and filters.
Usage (repository usage)
// foo-repository.ts
import type { Deps } from '.container'
export function makeAwesomeService({ fooRepository }: Deps) {
return {
async saveSomething(fooUuid: string) {
const foo = await fooRepository.findOne({uuid: fooUuid})
// ... do something with `foo`...
await fooRepository.save(foo)
return true
}
}
}Repository available methods
interface Repository<Model> {
// collection getter
getCollection: () => Collection<Model>
// finders & aggregate
find: (filter?: Filter<Model>, options?: FindOptions) => FindCursor<WithId<Model>>
findOne: (filter?: Filter<Model>, options?: FindOptions) => Promise<WithId<Model> | null>
aggregate: <T extends Document>(pipeline?: Document[], options?: AggregateOptions) => AggregationCursor<T>
// count & check
count: (filter?: Filter<Model>) => Promise<number>
exists: (filter?: Filter<Model>) => Promise<boolean>
// inserts
insert: (item: Model) => Promise<boolean>
insertMany: (items: Model[]) => Promise<number>
// updates
update: (filter: Filter<Model>, item: Partial<Model>) => Promise<boolean>
updateMany: (filter: Filter<Model>, item: Partial<Model>) => Promise<number>
upsert: (filter: Filter<Model>, item: Partial<Model>) => Promise<{
modifiedCount: number
upsertedCount: number
}>
// deletes
delete: (filter?: Filter<Model>) => Promise<boolean>
deleteMany: (filter?: Filter<Model>) => Promise<number>
}TODO
- createdAt/updatedAt auto fill option
- soft delete option
