express-mong

0.10.1 • Public • Published

express-mong

Mongoose wrapper to inject request object into mongoose Query, Document, and Hooks

Installation

$ npm install express-mong

Introduction

express-mong is a very thin layer of mongoose 'Model' and 'Query'. It enables to have request object in almost anywhere you access mongoose instances within that request scope, and also provides same interfaces as mongoose 'Model' does including callbacks.

Places you can find request object

You can find request object in:

  • Document

  • Document middleware -- validate -- save -- remove

  • Query middleware -- count -- deleteMany -- deleteOne -- find -- findOne -- findOneAndDelete -- findOneAndRemove -- findOneAndUpdate -- update -- updateOne -- updateMany -- replaceOne

  • Aggregate middleware

  • Methods

  • Statics

  • toObject

  • toJSON

Mongoose Middleware

Usage

const express = require('express');
const Mong = require('express-mong');
const app = express();

app.use(Mong());

const testSchema = new Schema({ name: String, reqPath: String });

testSchema.pre('save', function(next) {
  const req = this.$req; // find request object from $req in document
  this.reqPath = req.path;
  next();
});

testSchema.pre('find', function() {
  const req = this.$req; // find request object from $req in query instance
  //
  // if session user is defined in request, can use it to limit the result
  // const userId = req.user._id;
  // const query = this.getQuery();
  // query.createdBy = userId;
  // this.setQuery(query);
  //
});

mongoose.model('Test', testSchema);

app.get('/test', function(req, res, next) {
  const Test = req.mong.model('Test');

  const test = new Test({ name: 'test1' });
  test.save(function(err, doc) {
    const _req = doc.$req; // find request object from $req in document
    res.send(doc.reqPath) // send '/test' set from save pre-hook
  });
});

Document Decorator

You can set decorators for each mongoose schema and expect it to be run before document(s) been returned.

...

Mong.setDecorator('Test', function() {
  this.name += this.name;
  return this;
});

app.get('/test2', function(req, res, next) {
  Test.findOne({ name: 'test1' }).then(doc => {
    res.send(doc.name); // send 'test1test1' set from decorator
  });
});

You can also set more than one decorators in options when initializing express middleware.

...

app.use(Mong({
  decorators: {
    Test: function() {
      this.name += this.name;
      return this;
    },
    ...
  }
}));

Decorators can be either sync functions or async functions.

Original Document Object

By default, the wrapper injects the original document object into returning documents. The $original is an object converted by 'toObject' method of the original document.

...
app.get('/test3', function(req, res, next) {
  const data = { name: 'test2' };
  Test.findOne({ name: 'test1' }).then(doc => {
    doc.set(data);
    console.log(doc.name); // test2
    console.log(doc.$original.name); // test1

    res.send(doc.$original.name); // send 'test1' set from original document object
  });
});

You can disable it in the options.

...

app.use(Mong({
  keepOriginal: false,
  ...
}));

Audit plugin

express-mong provides one mongoose plugin to audit user and datetime on document's creation and updates. The user document / object must be set in request object as 'req.user'.

const mongAudit = require('express-mong/plugins/audit');
...

const testSchema = new Schema({ name: String, reqPath: String });
testSchema.plugin(mongAudit);
mongoose.model('Test', testSchema);

app.get('/test', function(req, res, next) {
  console.log(req.user); // session user

  const Test = req.mong('Test');

  Test.create({ name: 'test1' }).then(doc => {
    console.log(doc.createdBy); // session user id
    console.log(doc.updatedBy); // session user id
    console.log(doc.createdAt); // created datetime
    console.log(doc.updatedAt); // updated datetime; same as createdAt

    doc.name = 'test2';
    doc.save().then(doc => {
      console.log(doc.updatedBy); // session user id
      console.log(doc.updatedAt); // updated datetime; different from createdAt

      res.send('done');
    });
  });
});

The audit option may vary depends on schemas.

const mongAudit = require('express-mong/plugins/audit');
...

const testSchema = new Schema({ name: String, reqPath: String });
const auditOptions = {
  userSchema = 'User', // default to 'User'
  createdBy = 'createdBy', // default to 'createdBy' and false to disable the field
  updatedBy = 'updatedBy', // default to 'updatedBy' and false to disable the field
  createdAt = 'createdAt', // default to 'createdAt' and false to disable the field
  updatedAt = 'updatedAt', // default to 'updatedAt' and false to disable the field
};

testSchema.plugin(mongAudit, auditOptions);
mongoose.model('Test', testSchema);

Since audit fields are generated by the plugin, you can omit them in the schema.

MIT Licensed

Package Sidebar

Install

npm i express-mong

Weekly Downloads

0

Version

0.10.1

License

MIT

Unpacked Size

14.3 kB

Total Files

6

Last publish

Collaborators

  • smartahn
  • junminahn