@krknet/mongo
v3.0.0
Published
Schema-backed MongoDB models, connection helpers, and CLI utilities
Maintainers
Readme
@krknet/mongo
Schema-backed MongoDB models, connection helpers, and CLI utilities.
Installation
npm install @krknet/mongo mongodb @krknet/profiler@krknet/profiler is a peer dependency used for connection and CLI logging.
Quick Start
const { BaseModel, Connection } = require('@krknet/mongo')
const connection = new Connection('mongodb://localhost:27017/app')
class User extends BaseModel {
static get collection () {
return connection.collection('users')
}
static get _modelSchema () {
return {
name: { type: String, required: true, transformations: ['trim'] },
email: { type: String, required: true, transformations: ['trim', 'toLowerCase'] },
active: { type: Boolean, default: true },
}
}
}
async function main () {
await connection.connect()
const user = new User({ name: 'Ada Lovelace', email: '[email protected]' })
await user.save()
const stored = await User.get(user.__id)
const allUsers = await User.get()
console.log(stored.toJSON())
console.log(allUsers.map(entry => entry.title))
await connection.disconnect()
}
main().catch(console.error)Public API
Connection
Create a connection once and reuse it across your models.
const { Connection } = require('@krknet/mongo')
const connection = new Connection('localhost:27017/mydb', {
doLog: true,
connectionOptions: { maxPoolSize: 10 },
initiators: [async currentConnection => {
await currentConnection.collection('users').createIndex({ email: 1 }, { unique: true })
}],
})Available methods:
await connection.connect(extraOptions)await connection.disconnect()connection.collection(name)orconnection.get(name)
BaseModel
Extend BaseModel to define the collection and schema for a document type.
class Post extends BaseModel {
static get collection () {
return connection.collection('posts')
}
static get _modelSchema () {
return {
title: { type: String, required: true, transformations: ['trim'] },
slug: { type: String, required: true, transformations: ['trim', 'toLowerCase'] },
publishedAt: { type: Date, default: null },
}
}
}Important behavior:
new Model(data)sanitizes the input through the schema immediately.await Model.get()returns all entries.await Model.get(id)returns one entry by_id.await Model.get([ids])returns all matching entries.await Model.get(queryObject)returns all matching entries.await instance.save()inserts or replaces the backing document.instance.update(data)performs a shallow overwrite and re-sanitizes.instance.patch(data)performs a deep merge and re-sanitizes.
Base lifecycle fields are included automatically:
_id_createdAt_lastChangeAt
Schema
Use Schema directly when you need validation or parsing outside a model class.
const { Schema } = require('@krknet/mongo')
const profileSchema = new Schema({
name: { type: String, required: true, transformations: ['trim'] },
role: { type: String, default: 'user', transformations: ['trim', 'toLowerCase'] },
age: { type: Number, validators: [({ transformedValue }) => transformedValue >= 0] },
})
const parsed = profileSchema.parse({ name: ' Ada ', age: '36' })
const validation = profileSchema.validate({})Supported field options:
type: target type or array item typerequired: reject missing values or transformedundefined/nullvaluesdefault: value or factory function used when input is absent or nullalias: alternative input names to read before defaultingtransformations: built-in names or custom transformation functionsvalidators: custom validation callbacksprotected: metadata flag available to consumersschema: nested schema for array entries
Built-in transformations:
toLowerCasetoUpperCasetrimcapitalizetoIntegerfloorceillonger0orUndefinedlonger0orNulltruthyorUndefinedtruthyorNull
Collection Wrapper
connection.collection(name) returns a helper around the native MongoDB collection.
Available helpers:
aggregate(pipeline, options)count(query)createIndex(fields, options)distinct(field, query)drop()find(query, options)findOne(query, options)insert(documentOrDocuments)remove(query)removeOne(query)updateOne(query, replacement)patch(query, patch)patchOne(query, patch)rawfor direct access to the native driver collection
CLI Usage
CLIservice maps [model] [operation] arguments to built-in operations.
const { CLIservice } = require('@krknet/mongo')
const cli = new CLIservice({
dbConnection: connection,
models: [User, Post],
})
cli.query(process.argv)Examples:
node cli user list --output json
node cli user create
node cli post update 6650f1d6c6740a2d079a8a90
node cli user delete 6650f1d6c6740a2d079a8a90Supported operations:
listorlcreateorcupdateorudeleteord
Package executable:
npx @krknet/mongo migrate-lifecycle --config ./mongo.config.js
Notes
- Connection URIs without a protocol are normalized to
mongodb://.... - Models default to ObjectId-backed
_idvalues unless_idis defined in the model schema. - For driver features not wrapped by this package, use
connection.collection(name).raw.
Upgrade Guide to v3
The BaseModel Lifecycle fields _created / _lastChange have been renamed to _createdAt / _lastChangeAt.
Direct collection normalization example:
await connection.connect()
const result = await User.collection.raw.updateMany(
{ _created: { $exists: true }, _createdAt: { $exists: false } },
{ $rename: { _created: '_createdAt' } }
)
console.log(result.modifiedCount)
await connection.disconnect()The packaged migration command automates all four steps: rename _created, rename _lastChange, then remove any remaining legacy keys when both old and new field names exist.
CLI migration example:
Create a small config module that exports the connection and the models you want to migrate:
const { connection, User, Post } = require('./mongo-runtime')
module.exports = {
dbConnection: connection,
models: [User, Post],
}Run the migration with npx:
npx @krknet/mongo migrate-lifecycle --config ./mongo.config.js
npx @krknet/mongo migrate-lifecycle --config ./mongo.config.js User Post
npx @krknet/mongo migrate-lifecycle --uri mongodb://localhost:27017/app users posts
npx @krknet/mongo migrate-lifecycle --uri mongodb://localhost:27017/appWith --config, the command loads your runtime module, opens the provided connection once, runs direct updateMany migrations on each selected model collection, prints per-model counts, and then disconnects.
With --uri, the command creates its own connection. Any positional arguments after the URI are treated as collection names. If you omit them, it lists all collections in the selected database and migrates each non-system collection.
