-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
77 lines (65 loc) · 2.52 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*
* Extended find method with filter/limit/select/sort options for mongoose
* Copyright(c)2017 Jozef Butko <[email protected]>
* WTFPL License
*/
'use strict';
module.exports = function(schema) {
const ObjectId = require('mongoose').Types.ObjectId;
/**
* Extended find query with filter/limit/select/sort options for mongoose
* @param {object} query query
* @param {object} queryParams query params sent from FE
* @param {array} protectedKeys protected (not filterable) keys
* @param {array} populate populate for refs
* @param {function} cb callback
* @return {object|array} promise/array with found documents
*/
schema.statics.findAndFilter = function findAndFilter(query, queryParams, protectedKeys, populate, cb) {
query = query || {};
queryParams = queryParams || {};
protectedKeys = protectedKeys || [];
if (!Array.isArray(protectedKeys)) return 'protectedKeys must be of type array';
protectedKeys.push('__v');
// get schema keys
let schemaKeys = Object.keys(schema.paths);
// check if we can filter on key
let filterAttributes = schemaKeys.filter((key) => {
let isProtectedKey = protectedKeys.indexOf(key) > -1;
return !isProtectedKey;
});
let queryOptions = ['limit', 'skip', 'page', 'sort', 'select', 'populate'];
// prepare query
for (let param in queryParams) {
if (!queryOptions.indexOf(param) > -1 && filterAttributes.indexOf(param) > -1)
query[param] = queryParams[param];
// _ids are ObjectIds not a string
if (param == '_id')
query[param] = ObjectId(queryParams[param]);
let isProtectedKey = queryOptions.indexOf(param) === -1 && filterAttributes.indexOf(param) === -1;
if (isProtectedKey)
return Promise.reject({
message: `Not allowed to filter by ${param} param`,
code: 'protectedKeyFilterNotAllowed',
status: 400
});
}
// find query options
let options = {
sort: queryParams.sort || '',
limit: parseInt(queryParams.limit, 10) || '',
skip: parseInt(queryParams.skip, 10) || '',
populate: populate || '',
};
return this
.find(query, queryParams.select || '', options)
.then((result) => {
if (cb) return cb(null, result);
return result;
})
.catch((err) => {
if (cb) return cb({ message: err, status: 400 }, null);
return { message: err, status: 400 };
});
};
};