0.5.0 • Published 9 years ago

menquery v0.5.0

Weekly downloads
2
License
MIT
Repository
github
Last release
9 years ago

Menquery

JS Standard Style NPM version Build Status Coveralls Status Dependency Status Downloads

Querystring parser middleware for MongoDB, Express and Nodejs

Install

npm install --save menquery

Examples

Pagination

Menquery has a default schema to handle pagination. This is the most simple and common usage.

var menquery = require('menquery');

app.get('/posts', menquery.middleware(), function(req, res) {
  var query = req.menquery;

  Post.find(query.query, query.select, query.cursor).then(function(posts) {
    // posts are proper paginated here
  });
});

User requests /posts?page=2&limit=20&sort=-createdAt req.menquery will be:

req.menquery = {
  query: {},
  select: {},
  cursor: {
    limit: 20, 
    skip: 20, 
    sort: {createdAt: -1}
  }
}

User requests /posts?q=term&select=title,desc req.menquery will be:

req.menquery = {
  query: {
    keywords: /term/i
  },
  select: {
    title: 1,
    desc: 1
  },
  cursor: {
    // defaults
    limit: 30, 
    skip: 0, 
    sort: {name: 1}
  }
}

User requests /posts?select=-title&sort=name,-createdAt req.menquery will be:

req.menquery = {
  query: {},
  select: {
    title: 0
  },
  cursor: {
    limit: 30, 
    skip: 0, 
    sort: {
      name: 1,
      createdAt: -1
    }
  }
}

Custom schema

You can define a custom schema, which will be merged into menquery default schema (explained above).

var menquery = require('menquery');

app.get('/posts', menquery.middleware({
  after: {
    type: Date,
    paths: ['createdAt']
    operator: '$gte'
  }
}), function(req, res) {
  Post.find(req.menquery.query).then(function(posts) {
    // ...
  });
});

User requests /posts?after=2016-04-23 req.menquery will be:

req.menquery = {
  query: {
    createdAt: {$gte: 1461369600000}
  },
  select: {},
  cursor: {
    // defaults
    limit: 30, 
    skip: 0, 
    sort: {name: 1}
  }
}

Reusable schemas

You can create reusable schemas as well. Just instantiate a menquery.Schema object.

var menquery = require('menquery');

var schema = new menquery.Schema({
  tags: {
    type: [String],
  }
});

// user requests /posts?tags=world,travel
// req.menquery.query is {tags: {$in: ['world', 'travel']}}
app.get('/posts', menquery.middleware(schema));
app.get('/articles', menquery.middleware(schema));

Advanced schema

var menquery = require('menquery');

var schema = new menquery.Schema({
  active: Boolean, // shorthand to {type: Boolean}
  sort: '-createdAt', // shorthand to {type: String, default: '-createdAt'}
  term: {
    type: RegExp,
    paths: ['title', 'description'],
    bindTo: 'search' // default was 'query'
  },
  with_picture: {
    type: Boolean,
    paths: ['picture'],
    operator: '$exists'
  }
}, {
  page: false, // disable default parameter `page`
  limit: 'max_items' // change name of default parameter `limit` to `max_items`
});

app.get('/posts', menquery.middleware(schema), function(req, res) {
  // user requests /posts?term=awesome&with_picture=true&active=true&max_items=100
  // req.menquery.query is {picture: {$exists: true}, active: true}
  // req.menquery.cursor is {limit: 100, sort: {createdAt: -1}}
  // req.menquery.search is {$or: [{title: /awesome/i}, {description: /awesome/i}]}
});

Dynamic advanced schema

var menquery = require('menquery');
var schema = new menquery.Schema();

schema.formatter('scream', function(scream, value, param) {
  if (scream) {
    value = value.toUpperCase() + '!!!!!!!';
  }
  return value;
});

schema.param('text', null, {type: String}); // {type: String}
schema.param('text').option('scream', true); // {type: String, scream: true}
schema.param('text').value('help');
console.log(schema.param('text').value()); // HELP!!!!!!!

schema.validator('isPlural', function(isPlural, value, param) {
  return {
    valid: !isPlural || value.substr(-1) === 's',
    message: param.name + ' must be in plural form.'
  };
});

schema.param('text').option('isPlural', true); // {type: String, scream: true, isPlural: true}
console.log(schema.validate()); // false
schema.param('text', 'helps');
console.log(schema.validate()); // true
console.log(schema.param('text').value()); // HELPS!!!!!!!

schema.parser('elemMatch', function(elemMatch, value, path, operator) {
  if (elemMatch) {
    value = {[path]: {$elemMatch: {[elemMatch]: {[operator]: value}}}};
  }
  return value;
});

schema.param('text', 'ivegotcontrols');
console.log(schema.param('text').parse()); // {text: 'IVEGOTCONTROLS!!!!!!!'}

schema.param('text').option('elemMatch', 'prop');
console.log(schema.param('text').parse()); // {text: {$elemMatch: {prop: {$eq: 'IVEGOTCONTROLS!!!!!!!'}}}}

Error handling

// user requests /posts?category=world
var menquery = require('menquery');

var schema = new menquery.Schema({
  category: {
    type: String,
    enum: ['culture', 'general', 'travel']
  }
});

app.get('/posts', menquery.middleware(schema));

app.use(function(err, req, res, next) {
  res.status(400).json(err);
});

Response body will look like:

{
  "valid": false,
  "name": "enum",
  "enum": ["culture", "general", "travel"],
  "value": "world",
  "message": "category must be one of: culture, general, travel"
}

Contributing

This package was created with generator-rise. Please refer to there to understand the codestyle and workflow. Issues and PRs are welcome!

License

MIT © Diego Haz

0.5.0

9 years ago

0.4.0

9 years ago

0.3.2

10 years ago

0.3.1

10 years ago

0.3.0

10 years ago

0.2.0

10 years ago

0.1.4

10 years ago

0.1.3

10 years ago

0.1.1

10 years ago

0.1.0

10 years ago