UNPKG

@hatchpad/restmon

Version:

NodeJS package that allows mongoose models to handle rest-like parameters and cursors.

163 lines (146 loc) 5.23 kB
module.exports = function(mongoose, secret) { var RestmonQuery = require('./RestmonQuery')(secret); var RestmonCursor = require('./RestmonCursor')(secret); if (!mongoose) { throw new Error('mongoose is required'); } var Restmon = function(name, schema, config, doBeforeModelCreation, schemaOptions) { config = config || {}; config.ignoreCase = (config.ignoreCase === false) ? false : true; config.id = config.id || '_id'; config.updated = config.updated || 'updated'; this.config_ = config; this.schema_ = schema; this.schemaOptions_ = schemaOptions; this.generateMongooseSchema(schema); if (schemaOptions && schemaOptions.plugins) { schemaOptions.plugins.forEach(function(plugin) { this.mongooseSchema_.plugin(plugin.plugin, plugin.opts); }.bind(this)); } if (doBeforeModelCreation) { doBeforeModelCreation.bind(this)(); } this.model = mongoose.model(name, this.mongooseSchema_); }; Restmon.prototype.isIgnoreCase = function(fieldName) { if (fieldName === this.config_.updated) return false; var property = this.schema_[fieldName]; if (property.type != String) return false; if (property.ignoreCase === true) return true; if (property.ignoreCase === false) return false; return this.config_.ignoreCase; }; Restmon.prototype.generateMongooseSchema = function(schema) { var key, property, builtSchema; this.sortables_ = []; builtSchema = {}; if (!schema[this.config_.updated]) { builtSchema[this.config_.updated] = {type:Date, default:Date.now, sortable:true}; } this.sortables_.push(this.config_.updated); for (key in schema) { property = schema[key]; builtSchema[key] = property; if (typeof property == 'object' && property.sortable) { if (this.isIgnoreCase(key) && property.type == String) { builtSchema['_' + key] = schema[key] builtSchema['_' + key].index = true; } else { builtSchema[key].index = true; } this.sortables_.push(key); } } this.mongooseSchema_ = new mongoose.Schema(builtSchema, this.schemaOptions_); }; Restmon.prototype.save = function(entity, cb) { var key; for (key in entity) { if (this.schema_[key] && this.schema_[key].sortable && this.schema_[key].type == String && this.isIgnoreCase(key) && entity.isModified(key)) { if (entity[key]) { entity['_' + key] = entity[key].toLowerCase(); } else { entity['_' + key] = entity[key]; } } } entity[this.config_.updated] = Date.now(); entity.save(cb); }; Restmon.prototype.update = function(conditions, doc, options, cb) { var key; for (key in doc) { if (this.schema_[key] && this.schema_[key].sortable && this.schema_[key].type == String && this.isIgnoreCase(key)) { if (doc[key]) { doc['_' + key] = doc[key].toLowerCase(); } else if (doc[key] !== undefined) { doc['_' + key] = doc[key]; } } } doc[this.config_.updated] = Date.now(); this.model.update(conditions, doc, options, cb); }; Restmon.prototype.create = function(entities, cb) { if (!Array.isArray(entities)) { this.save(entities, cb); return; } entities.forEach(function(entity) { for (key in entity) { if (this.schema_[key] && this.schema_[key].sortable && this.schema_[key].type == String && this.isIgnoreCase(key) && entity.isModified(key)) { entity['_' + key] = entity[key] ? entity[key].toLowerCase() : entity[key]; } } entity[this.config_.updated] = Date.now(); }.bind(this)); this.model.create(entities, cb); }; Restmon.prototype.find = function(criteria, cb) { var crit = {$and: []}; if (criteria && criteria != {}) { crit.$and.push(this.getCriteria(criteria)); } var q = this.model.find(crit, cb); return new RestmonQuery(this, q); }; Restmon.prototype.findOne = function(criteria, cb) { var crit = {$and: []}; if (criteria && criteria != {}) { crit.$and.push(this.getCriteria(criteria)); } var q = this.model.findOne(crit, cb); return new RestmonQuery(this, q); }; Restmon.prototype.getCursor = function(entity) { var cursor, property; cursor = {}; for(key in this.schema_) { property = this.schema_[key]; if (property.sortable) { cursor[key] = entity[key]; } } cursor[this.config_.id] = entity[this.config_.id]; cursor[this.config_.updated] = entity[this.config_.updated]; return new RestmonCursor(cursor); }; Restmon.prototype.getCriteria = function(rawCriteria) { if (!rawCriteria || typeof rawCriteria !== 'object') { return rawCriteria; } var key, criteria; criteria = {}; for(key in rawCriteria) { if (typeof(key) === 'string' && this.schema_[key] && this.schema_[key].sortable && this.isIgnoreCase(key)) { criteria['_' + key] = rawCriteria[key].toLowerCase(); } else { criteria[key] = rawCriteria[key]; } } return criteria; }; Restmon.Cursor = RestmonCursor; return Restmon; };