Security News
Input Validation Vulnerabilities Dominate MITRE's 2024 CWE Top 25 List
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Elegant MongoDB driver for Node.js.
$ npm i mongolass --save
const Mongolass = require('mongolass')
const mongolass = new Mongolass()
mongolass.connect('mongodb://localhost:27017/test')// const mongolass = new Mongolass('mongodb://localhost:27017/test')
const User = mongolass.model('User')
User
.find()
.select({ name: 1, age: 1 })
.sort({ name: -1 })
.exec()
.then(console.log)
.catch(console.error)
Or use optional schema:
const Mongolass = require('mongolass')
const Schema = Mongolass.Schema
const mongolass = new Mongolass('mongodb://localhost:27017/test')
const UserSchema = new Schema('UserSchema', {
name: { type: 'string', required: true },
age: { type: 'number', default: 18 }
})
const User = mongolass.model('User', UserSchema)
/*
equal to:
const User = mongolass.model('User', {
name: { type: 'string', required: true },
age: { type: 'number', default: 18 }
})
will create inner schema named `UserSchema`.
*/
User
.insertOne({ name: 'nswbmw', age: 'wrong age' })
.exec()
.then(console.log)
.catch(console.error)
/*
{ TypeError: ($.age: "wrong age") ✖ (type: number)
at Model.insertOne (/Users/nswbmw/Desktop/test/node_modules/mongolass/lib/query.js:101:16)
at Object.<anonymous> (/Users/nswbmw/Desktop/test/app.js:21:4)
at Module._compile (module.js:635:30)
at Object.Module._extensions..js (module.js:646:10)
at Module.load (module.js:554:32)
at tryModuleLoad (module.js:497:12)
at Function.Module._load (module.js:489:3)
at Function.Module.runMain (module.js:676:10)
at startup (bootstrap_node.js:187:16)
at bootstrap_node.js:608:3
validator: 'type',
path: '$.age',
actual: 'wrong age',
expected: { type: 'number', default: 18 },
schema: 'UserSchema',
model: 'User',
op: 'insertOne',
args: [ { name: 'nswbmw', age: 'wrong age' } ],
pluginName: 'MongolassSchema',
pluginOp: 'beforeInsertOne',
pluginArgs: [] }
*/
ObjectId schema:
'use strict'
const Mongolass = require('mongolass')
const Schema = Mongolass.Schema
const mongolass = new Mongolass('mongodb://localhost:27017/test')
const Post = mongolass.model('Post', {
author: { type: Mongolass.Types.ObjectId }
}, { collName: 'post' })
Post.insertOne({ author: '111111111111111111111111' })
.then(function () {
return Post.find({ author: '111111111111111111111111' })
})
.then(console.log)
/*
[ { _id: 57caed24ecda6ffb15962591,
author: 111111111111111111111111 } ]
*/
NB: You can pass collName
as collection name.
Same as node-mongodb-native.
知乎:从零开始写一个 Node.js 的 MongoDB 驱动库
I've been using Mongoose for years, it's great but complex sucks, so i wrote Mongolass. Mongolass is not simply mimicking Mongoose, but rather draw on the advantages of mongoose redesigned the architecture. Mongolass has some exciting features different from Mongoose:
Schemas not only define the structure of your document and casting of properties, they also define document instance methods, static Model methods, compound indexes and document lifecycle hooks called middleware.
In Mongolass, Schema is only used for defining the structure of your document and casting of properties, Model used for retrievaling data from mongodb and register plugins, Entity(as result) is plain object. Schema is also optional.
.pre
, .post
, use async next()
. In Mongolass, we can register a plugin for Model or global mongolass instance. like:User.plugin('xx', {
beforeFind: function (...args) {},// or function return Promise
afterFind: async function (result, ...args) {
console.log(result, args)
...
},
// afterFind: async function (result, ...args) {
// console.log(result, args)
// ...
// }
})
Above added two hook functions for User
, when User.find().xx().exec()
is called, the execution order is as follows:
beforeFind(handle query args) -> retrieve data from mongodb -> afterFind(handle query result)
Mongolass's plugins could be substituted for Mongoose's (document instance methods + static Model methods + plugins).
User
.insertOne({ name: 'nswbmw', age: 'wrong age' })
.exec()
.then(console.log)
.catch(console.error)
/*
{ TypeError: ($.age: "wrong age") ✖ (type: number)
at Model.insertOne (/Users/nswbmw/Desktop/test/node_modules/mongolass/lib/query.js:105:16)
at Object.<anonymous> (/Users/nswbmw/Desktop/test/app.js:23:4)
at Module._compile (module.js:573:30)
at Object.Module._extensions..js (module.js:584:10)
at Module.load (module.js:507:32)
at tryModuleLoad (module.js:470:12)
at Function.Module._load (module.js:462:3)
at Function.Module.runMain (module.js:609:10)
at startup (bootstrap_node.js:158:16)
at bootstrap_node.js:598:3
validator: 'type',
actual: 'wrong age',
expected: { type: 'number' },
path: '$.age',
schema: 'UserSchema',
model: 'User',
op: 'insertOne',
args: [ { name: 'nswbmw', age: 'wrong age' } ],
pluginName: 'MongolassSchema',
pluginOp: 'beforeInsertOne',
pluginArgs: [] }
*/
According to the error instance, esay to know age
expect a number but got a string, from error stack know it's broken on app.js:23:4
and the operator is Model.insertOne
.
see another-json-schema, support default
and required
.
const Mongolass = require('mongolass')
const mongolass = new Mongolass('mongodb://localhost:27017/test')
const User = mongolass.model('User', {
name: { type: 'string', required: true },
age: { type: 'number', default: 18 }
})
;(async function () {
await User.insert({ age: 17 })
})().catch(console.error)
Output:
{ TypeError: ($.name: undefined) ✖ (required: true)
at Model.insert (/Users/nswbmw/Desktop/test/node_modules/mongolass/lib/query.js:101:16)
at /Users/nswbmw/Desktop/test/app.js:10:14
at Object.<anonymous> (/Users/nswbmw/Desktop/test/app.js:11:3)
at Module._compile (module.js:635:30)
at Object.Module._extensions..js (module.js:646:10)
at Module.load (module.js:554:32)
at tryModuleLoad (module.js:497:12)
at Function.Module._load (module.js:489:3)
at Function.Module.runMain (module.js:676:10)
at startup (bootstrap_node.js:187:16)
validator: 'required',
path: '$.name',
actual: undefined,
expected: { type: 'string', required: true },
schema: 'UserSchema',
model: 'User',
op: 'insert',
args: [ { age: 17 } ],
pluginName: 'MongolassSchema',
pluginOp: 'beforeInsert',
pluginArgs: [] }
const Mongolass = require('mongolass')
const mongolass = new Mongolass('mongodb://localhost:27017/test')
const User = mongolass.model('User', {
name: { type: 'string', required: true },
age: { type: 'number', default: 18 }
})
;(async function () {
await User.insert({ name: 'nswbmw' })
const user = await User.findOne({ name: 'nswbmw' })
console.log(user)
// { _id: 5a530c5d39d9a4eb3aa57856, name: 'nswbmw', age: 18 }
})()
What's difference between number
and Mongolass.Types.Number
?
number
only check type, Mongolass.Types.Number
will try to convert value to a number, if failed then throw error.
mongolass.plugin(pluginName, hooks)// register global plugin
User.plugin(pluginName, hooks)// register model plugin
example:
const moment = require('moment')
const Mongolass = require('mongolass')
const mongolass = new Mongolass('mongodb://localhost:27017/test')
const User = mongolass.model('User')
mongolass.plugin('addCreatedAt', {
beforeInsert: function (format) {
console.log('beforeInsert', this._op, this._args, format)
// beforeInsert insert [ { firstname: 'san', lastname: 'zhang' } ] YYYY-MM-DD
this._args[0].createdAt = moment().format(format)
}
})
User.plugin('addFullname', {
afterFindOne: function (user, opt) {
console.log('afterFindOne', this._op, this._args, opt)
// afterFindOne findOne [] { sep: '-' }
if (!user) return user
user.fullname = user.firstname + opt.sep + user.lastname
return user
},
afterFind: async function (users, opt) {
console.log('afterFind', this._op, this._args, opt)
// afterFind find [ { firstname: 'san' } ] { sep: ' ' }
if (!users.length) return users
return users.map(user => {
user.fullname = user.firstname + opt.sep + user.lastname
return user
})
}
})
;(async function () {
// when use await, .exec() is omissible.
await User.insert({ firstname: 'san', lastname: 'zhang' }).addCreatedAt('YYYY-MM-DD')
console.log(await User.findOne().addFullname({ sep: '-' }))
// { _id: 5850186544c3b82d23a82e45,
// firstname: 'san',
// lastname: 'zhang',
// createdAt: '2016-12-13',
// fullname: 'san-zhang' }
console.log(await User.find({ firstname: 'san' }).addFullname({ sep: ' ' }))
// [ { _id: 5850186544c3b82d23a82e45,
// firstname: 'san',
// lastname: 'zhang',
// createdAt: '2016-12-13',
// fullname: 'san zhang' } ]
})().catch(console.error)
NOTE: Different order of calling plugins will output different results. The priority of Model's plugins is greater than global's.
example:
const Mongolass = require('mongolass')
const mongolass = new Mongolass('mongodb://localhost:27017/test')
const User = mongolass.model('User')
User.plugin('add2', {
afterFindOne: function (user) {
if (!user) return user
user.name = `${user.name}2`
return user
}
})
User.plugin('add3', {
afterFindOne: async function (user) {
if (!user) return user
user.name = `${user.name}3`
return user
}
})
;(async function () {
await User.insert({ name: '1' })
console.log(await User.findOne().add2().add3())
// { _id: 58501a8a7cc264af259ca691, name: '123' }
console.log(await User.findOne().add3().add2())
// { _id: 58501a8a7cc264af259ca691, name: '132' }
})().catch(console.error)
see mongolass-plugin-populate.
Mongolass has some built-in plugins, only for find
and findOne
.
example:
const co = require('co')
const Mongolass = require('mongolass')
const mongolass = new Mongolass('mongodb://localhost:27017/test')
const User = mongolass.model('User')
;(async function () {
await User.insert({ name: '1' })
await User.insert({ name: '2' })
const result = await User
.find()
.skip(1)
.limit(1)
console.log(result)
// [ { _id: 58501c1281ea915a2760a2ee, name: '2' } ]
})().catch(console.error)
$ npm test (coverage 100%)
MIT
4.2.0/2018-04-13
FAQs
Elegant MongoDB driver for Node.js.
The npm package mongolass receives a total of 63 weekly downloads. As such, mongolass popularity was classified as not popular.
We found that mongolass demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.
Research
Security News
A threat actor's playbook for exploiting the npm ecosystem was exposed on the dark web, detailing how to build a blockchain-powered botnet.