UNPKG

@rill/mongoose

Version:

Resource based crud api generator for Rill and Mongoose.

120 lines (104 loc) 3.19 kB
'use strict' var mongoose = require('mongoose') var mutils = require('mongoose/lib/utils') var del = require('del-values') var hiddenPath = /(^_|\._).*/g var monStr = /-?([^, ]+)/g var popSub = /:(.*)/ var popSelect = /\[([^\]]+)\]/ var popOptions = { lean: true } var HIDDEN_FIELDS = '__rill_mongoose_hidden__' module.exports = { getHiddenFields: getHiddenFields, parsePopulate: parsePopulate, defaultSelect: defaultSelect, omitQuery: omitQuery, omitObj: omitObj, omitStr: omitStr, assign: assign } // Extract hidden fields from a Model function getHiddenFields (model) { if (model[HIDDEN_FIELDS]) return model[HIDDEN_FIELDS] var hidden = [] if (model && model.schema) { model.schema.eachPath(function (path, type) { var options = type.options if (path === '_id') return if (options.hidden === false) return if (options.hidden === true || hiddenPath.test(path)) hidden.push(path) }) } model[HIDDEN_FIELDS] = hidden return hidden } // Parse populate string with mongoose utils. function parsePopulate (from, paths) { if (!from || !from.schema || typeof paths !== 'string') return var fields = mutils.populate(paths, null, from) for (var i = fields.length, it, field, model; i--;) { it = fields[i] it.path = it.path .replace(popSub, function (m, populate) { it.populate = populate return '' }) .replace(popSelect, function (m, select) { it.select = select return '' }) field = from.schema.path(it.path) if (!field || !field.options.ref) { fields.splice(i, 1) continue } try { model = mongoose.model(field.options.ref) } catch (e) { fields.splice(i, 1) continue } var hidden = getHiddenFields(model) it.path = field.path it.model = model it.options = popOptions it.select = omitStr(it.select, hidden) || defaultSelect(model) it.populate = parsePopulate(it.model, omitStr(it.populate, hidden)) } return fields } // Build a default select query for a model based on hidden fields. function defaultSelect (model) { var hidden = getHiddenFields(model) if (!hidden) return var result = new Array(hidden.length) for (var i = result.length; i--;) result[i] = '-' + hidden[i] return result.join(' ') } // Remove mongo query style fields from an object. function omitQuery (it, fields) { if (it.$or) omitQuery(it.$or, fields) if (it.$and) omitQuery(it.$and, fields) if (it.$nor) omitQuery(it.$nor, fields) omitObj(it, fields) return it } // Remove all fields from an object. function omitObj (it, fields) { if (!fields) return it if (!it || typeof it !== 'object') return if (Array.isArray(it)) for (var i = it.length; i--;) omitObj(it[i], fields) return del(it, fields) } // Remove all fields from a string. function omitStr (it, fields) { if (!fields) return it if (typeof it !== 'string') return var m var arr = [] while ((m = monStr.exec(it))) if (!~fields.indexOf(m[1])) arr.push(m[0]) return arr.join(' ') } // Assign keys from one object to another. function assign (dst, src) { for (var key in src) dst[key] = src[key] return dst }