
Research
Malicious npm Packages Impersonate Flashbots SDKs, Targeting Ethereum Wallet Credentials
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
@stejnar/mongoopose
Advanced tools
Mongoopose is very simple and currently provides by far not all of the mongoose api. It wraps mongoose and behaves like an adapter, based on functional programming patterns and Promises to escape the pyramid of doom.
Combining function composition and Promises comes in very handy, when complex database queries make your head hurt. Your code becomes more readable and easier to reason about, because you will start to see how your data flows.
Mongoopose itself has only a few very basic wrapper functions like find, findOne, save and remove, but leaves you with a simple possibility to compose every async task into the pipeline.
Most likely you would have a basic understanding of functional programming, but happily you do not need it to just use it, because the implementation is very straight forward.
There is no npm dependency as you can see in package.json, because mongoopose uses
dependency injection.
In a nutshell... it depends on mongoose, which means you also have a MongoDB setup.
npm install @stejnar/mongoopose
Enough talking. Here is some code:
Simple findOne and update example:
const mongoopose = require('mongoopose')
const mongoose = require('mongoose')
// initialize mongoose model
const userSchema = require('./schema')
const UserModel = mongoose.model('User', userSchema)
// initialize mongoopose model
const {compose, Params} = mongoopose
const User = mongoopose.model(UserModel)
// design the queries
const selectJon = params => Params({select: {email: 'jon-snow@iron-throne.com'}})
const updateJon = params => Params({query: {$set: {lifes: 2}}})
// composition reads from left to right
const pipeline = compose(
User.findOne(selectJon),
User.update(updateJon)
)
pipeline(Params()) // empty initial params
.then(params => console.log(params)) // params.user => jon
.catch(error => console.error(error))
Login routine with express.js:
router.post('/login', function (req, res) {
// find user by name and pass as 'user'
const findUser = params => Params({ select: { name: params.request.name }, as: 'user' })
// bycrpt compare action for pipeline
const comparePasswords = (resolve, reject, params) => {
const { request, user } = params
bcrypt.compare(request.password, user.password, (err, same) => {
if (same) {
const { _id, name } = user
resolve(params.add(jwt.sign({ _id, name }, 'ssshhhhh secret'), 'token'))
} else if (err) {
reject(params.toError({ status: 500 }))
} else {
reject(params.toError({ status: 403, message: 'Unequal passwords' }))
}
})
}
// find additional user data
const findPhotos = params => Params({ select: { user: params.user._id }, as: 'photos' })
// initiate pipeline
const pipeline = compose(
User.findOne(findUser),
User.pipe(comparePasswords),
Photos.find(findPhotos)
)
// set initial params
const params = { request: req.body.payload }
// handle results or errros
pipeline(Params(params))
.then(({ user, token, photos }) => {
const { _id: id, name } = user
res.success(
'Successfully logged in',
{ user: { id, name }, token, photos }
);
})
.catch(res.error)
});
See functors.test.js for more examples
Parameters:
Returns:
Model
You should only pass findById(), findOne(), find(), save(), update(), remove() and/or pipe() Nested arrays are allowed, they will get flattened, keeping the original order.
Parameter:
Returns:
function(Parameters), that returns a Promise
Note: All methods, but pipe(), take the same input and give the same output. As follows:
Parameter:
query: function(query = Parameters => Parameters),
optional and defaults into no Parameters transformation
Returns:
function(Parameters), that returns a Promise
Parameter:
function(action), action can be any function that gets resolve, reject and params passed into and calls resolve or reject
Returns:
function(Parameters), that returns a Promise
Type: Function
Shorthand for new Parameters().assign(obj)
Parameter:
Returns:
new Instance of Parameters
Type: String
Default: mongoose.Model.modelName
This is the key with that a queries result gets assigned to Parameters.
Type: Object
This is the selector that gets passed into mongoose queries.
Type: Object
This is the update object for Model.update()
Type: Object
This gets passed into the mongoose model constructor for Model.save().
Parameters:
Returns:
Parameters
Type: Function
Resets the Parameters.as key to undefined and merges obj into it.
Parameters:
Returns:
Parameters
Wraps this instance of Parameters into an Error.
Parameters:
Returns:
Error
FAQs
functional programming for mongoose
We found that @stejnar/mongoopose 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.
Research
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
Security News
Ruby maintainers from Bundler and rbenv teams are building rv to bring Python uv's speed and unified tooling approach to Ruby development.
Security News
Following last week’s supply chain attack, Nx published findings on the GitHub Actions exploit and moved npm publishing to Trusted Publishers.