Comparing version 1.3.4 to 1.3.6
@@ -7,9 +7,11 @@ 'use strict'; | ||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); | ||
let mongoskin; | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | ||
// if npm version is >= 3.x, mongoskin must be required directly | ||
try { | ||
mongoskin = require('monk/node_modules/mongoskin'); | ||
} catch (_) { | ||
mongoskin = require('mongoskin'); | ||
} | ||
const ObjectID = require('monk/node_modules/mongoskin').ObjectID; | ||
const mongoskin = require('monk/node_modules/mongoskin'); | ||
const pluralize = require('pluralize'); | ||
@@ -21,9 +23,9 @@ const compose = require('koa-compose'); | ||
const wrap = require('co-monk'); | ||
const _get = require('get-value'); | ||
const _set = require('set-value'); | ||
const get = require('get-value'); | ||
const set = require('set-value'); | ||
const is = require('is_js'); | ||
const Query = require('./query'); | ||
const util = require('./util'); | ||
/** | ||
@@ -35,7 +37,3 @@ * Mongorito | ||
var Mongorito = (function () { | ||
function Mongorito() { | ||
_classCallCheck(this, Mongorito); | ||
} | ||
class Mongorito { | ||
/** | ||
@@ -47,8 +45,20 @@ * Connect to a MongoDB database and return connection object | ||
*/ | ||
static connect () { | ||
// parse arguments | ||
let args = Array.prototype.slice.call(arguments); | ||
Mongorito.connect = function connect() { | ||
for (var _len = arguments.length, urls = Array(_len), _key = 0; _key < _len; _key++) { | ||
urls[_key] = arguments[_key]; | ||
} | ||
let urls = []; | ||
let options = {}; | ||
args.forEach(function (arg) { | ||
if (is.string(arg)) { | ||
urls.push(arg); | ||
} | ||
if (is.object(arg)) { | ||
options = arg; | ||
} | ||
}); | ||
// convert mongo:// urls to monk-supported ones | ||
@@ -59,11 +69,14 @@ urls = urls.map(function (url) { | ||
var db = monk.apply(undefined, urls); | ||
let db = monk(urls, options); | ||
// if there is already a connection | ||
// don't overwrite it with a new one | ||
if (!this.db) this.db = db; | ||
if (!this.db) { | ||
this.db = db; | ||
} | ||
return db; | ||
}; | ||
} | ||
/** | ||
@@ -74,7 +87,8 @@ * Disconnect from a database | ||
*/ | ||
Mongorito.disconnect = function disconnect() { | ||
static disconnect () { | ||
this.db.close(); | ||
}; | ||
} | ||
/** | ||
@@ -85,7 +99,8 @@ * Alias for .disconnect() | ||
*/ | ||
Mongorito.close = function close() { | ||
static close () { | ||
return this.disconnect.apply(this, arguments); | ||
}; | ||
} | ||
/** | ||
@@ -96,7 +111,7 @@ * Return a co-wrapped monk collection | ||
*/ | ||
static _collection (db, name) { | ||
let url = db.driver._connect_args[0]; | ||
let collections = this._collections[url]; | ||
Mongorito._collection = function _collection(db, name) { | ||
var url = db.driver._connect_args[0]; | ||
var collections = this._collections[url]; | ||
if (!collections) { | ||
@@ -106,12 +121,14 @@ collections = this._collections[url] = {}; | ||
if (collections[name]) return collections[name]; | ||
if (collections[name]) { | ||
return collections[name]; | ||
} | ||
var collection = db.get(name); | ||
let collection = db.get(name); | ||
collections[name] = wrap(collection); | ||
return collections[name]; | ||
}; | ||
} | ||
} | ||
return Mongorito; | ||
})() | ||
@@ -124,6 +141,5 @@ /** | ||
; | ||
Mongorito._collections = {}; | ||
/** | ||
@@ -133,13 +149,8 @@ * Model | ||
var Model = (function () { | ||
function Model() { | ||
var attrs = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
_classCallCheck(this, Model); | ||
this.attributes = clone(attrs); | ||
class Model { | ||
constructor (attrs, options) { | ||
this.attributes = clone(attrs || {}); | ||
this.changed = {}; | ||
this.previous = {}; | ||
this.options = clone(options); | ||
this.options = clone(options || {}); | ||
@@ -169,2 +180,3 @@ // reset hooks | ||
/** | ||
@@ -175,4 +187,37 @@ * Get collection for current model | ||
*/ | ||
get _collection () { | ||
if (is.string(this.collection)) { | ||
return Mongorito._collection(this._db, this.collection); | ||
} | ||
// get collectio name | ||
// from the "collection" property | ||
// or generate the default one | ||
let defaultName = pluralize(this.constructor.name).toLowerCase(); | ||
let name = result(this, 'collection', defaultName); | ||
// save collection name | ||
// to avoid the same check in future | ||
this.collection = this.constructor.prototype.collection = name; | ||
return Mongorito._collection(this._db, this.collection); | ||
} | ||
/** | ||
* Get database for current model | ||
* | ||
* @api private | ||
*/ | ||
get _db () { | ||
// use either custom database | ||
// specified for this model | ||
// or use a default one | ||
return this.db || Mongorito.db; | ||
} | ||
/** | ||
* Get model attribute | ||
@@ -183,13 +228,14 @@ * | ||
*/ | ||
Model.prototype.get = function get(key) { | ||
get (key) { | ||
// if key is empty | ||
// return all attributes | ||
var value = key ? _get(this.attributes, key) : this.attributes; | ||
let value = key ? get(this.attributes, key) : this.attributes; | ||
// if value is object | ||
// return a deep copy | ||
return value && value.constructor === Object ? clone(value) : value; | ||
}; | ||
} | ||
/** | ||
@@ -202,37 +248,32 @@ * Set model attribute | ||
*/ | ||
Model.prototype.set = function set(key, value) { | ||
var _this = this; | ||
set (key, value) { | ||
// if object passed instead of key-value pair | ||
// iterate and call set on each item | ||
if (is.object(key)) { | ||
var _ret = (function () { | ||
var attrs = key; | ||
var keys = Object.keys(attrs); | ||
let attrs = key; | ||
let keys = Object.keys(attrs); | ||
keys.forEach(function (key) { | ||
_this.set(key, attrs[key]); | ||
}); | ||
let self = this; | ||
return { | ||
v: undefined | ||
}; | ||
})(); | ||
keys.forEach(function (key) { | ||
self.set(key, attrs[key]); | ||
}); | ||
if (typeof _ret === 'object') return _ret.v; | ||
return; | ||
} | ||
// check if the value actually changed | ||
var previousValue = this.get(key); | ||
let previousValue = this.get(key); | ||
if (previousValue !== value) { | ||
_set(this.previous, key, previousValue); | ||
_set(this.attributes, key, value); | ||
_set(this.changed, key, true); | ||
set(this.previous, key, previousValue); | ||
set(this.attributes, key, value); | ||
set(this.changed, key, true); | ||
} | ||
return value; | ||
}; | ||
} | ||
/** | ||
@@ -244,7 +285,8 @@ * Unset model attribute | ||
*/ | ||
Model.prototype.unset = function unset(key) { | ||
unset (key) { | ||
this.set(key, undefined); | ||
}; | ||
} | ||
/** | ||
@@ -255,19 +297,20 @@ * Set default values | ||
*/ | ||
_setDefaults () { | ||
let defaults = result(this, 'defaults', {}); | ||
let keys = Object.keys(defaults); | ||
Model.prototype._setDefaults = function _setDefaults() { | ||
var _this2 = this; | ||
let self = this; | ||
var defaults = result(this, 'defaults', {}); | ||
var keys = Object.keys(defaults); | ||
keys.forEach(function (key) { | ||
var defaultValue = defaults[key]; | ||
var actualValue = _this2.get(key); | ||
let defaultValue = defaults[key]; | ||
let actualValue = self.get(key); | ||
if (is.undefined(actualValue)) { | ||
_this2.set(key, defaultValue); | ||
self.set(key, defaultValue); | ||
} | ||
}); | ||
}; | ||
} | ||
/** | ||
@@ -278,7 +321,8 @@ * Get all attributes | ||
*/ | ||
Model.prototype.toJSON = function toJSON() { | ||
toJSON () { | ||
return this.attributes; | ||
}; | ||
} | ||
/** | ||
@@ -290,5 +334,8 @@ * Configure model (usually, set hooks here) | ||
*/ | ||
configure () { | ||
Model.prototype.configure = function configure() {}; | ||
} | ||
/** | ||
@@ -301,5 +348,8 @@ * Rollback given method when error occurs | ||
*/ | ||
Model.prototype.rollback = function* rollback() {}; | ||
* rollback () { | ||
} | ||
/** | ||
@@ -311,5 +361,5 @@ * Return a function, that in case of an error | ||
*/ | ||
Model.prototype._rollbackFor = function _rollbackFor(method) { | ||
return function* (next) { | ||
_rollbackFor (method) { | ||
return function * (next) { | ||
try { | ||
@@ -322,4 +372,5 @@ yield* next; | ||
}; | ||
}; | ||
} | ||
/** | ||
@@ -330,6 +381,6 @@ * Add hooks | ||
*/ | ||
hook (when, action, method) { | ||
let self = this; | ||
Model.prototype.hook = function hook(when, action, method) { | ||
var _this3 = this; | ||
// if object is given | ||
@@ -339,23 +390,15 @@ // iterate and call .hook() | ||
if (is.object(when)) { | ||
var _ret2 = (function () { | ||
var hooks = when; | ||
var keys = Object.keys(hooks); | ||
let hooks = when; | ||
let keys = Object.keys(hooks); | ||
keys.forEach(function (key) { | ||
var _key$split = key.split(':'); | ||
keys.forEach(function (key) { | ||
let parts = key.split(':'); | ||
let when = parts[0]; | ||
let action = parts[1]; | ||
let method = hooks[key]; | ||
var when = _key$split[0]; | ||
var action = _key$split[1]; | ||
self.hook(when, action, method); | ||
}); | ||
var method = hooks[key]; | ||
_this3.hook(when, action, method); | ||
}); | ||
return { | ||
v: undefined | ||
}; | ||
})(); | ||
if (typeof _ret2 === 'object') return _ret2.v; | ||
return; | ||
} | ||
@@ -367,6 +410,6 @@ | ||
if (is.array(method)) { | ||
var _methods = method; | ||
let methods = method; | ||
_methods.forEach(function (method) { | ||
return _this3.hook(when, action, method); | ||
methods.forEach(function (method) { | ||
return self.hook(when, action, method); | ||
}); | ||
@@ -379,3 +422,5 @@ | ||
// get the function | ||
if (is.not['function'](method)) method = this[method]; | ||
if (is.not.function(method)) { | ||
method = this[method]; | ||
} | ||
@@ -391,4 +436,5 @@ // around hooks should be | ||
} | ||
}; | ||
} | ||
/** | ||
@@ -399,7 +445,8 @@ * Add multiple hooks at once | ||
*/ | ||
Model.prototype.hooks = function hooks() { | ||
hooks () { | ||
return this.hook.apply(this, arguments); | ||
}; | ||
} | ||
/** | ||
@@ -412,7 +459,8 @@ * Add before:* hook | ||
*/ | ||
Model.prototype.before = function before(action, method) { | ||
before (action, method) { | ||
this.hook('before', action, method); | ||
}; | ||
} | ||
/** | ||
@@ -425,7 +473,8 @@ * Add after:* hook | ||
*/ | ||
Model.prototype.after = function after(action, method) { | ||
after (action, method) { | ||
this.hook('after', action, method); | ||
}; | ||
} | ||
/** | ||
@@ -438,7 +487,8 @@ * Add around:* hook | ||
*/ | ||
Model.prototype.around = function around(action, method) { | ||
around (action, method) { | ||
this.hook('around', action, method); | ||
}; | ||
} | ||
/** | ||
@@ -449,16 +499,18 @@ * Execute hooks | ||
*/ | ||
_runHooks (when, action, options) { | ||
if (!options) { | ||
options = {}; | ||
} | ||
Model.prototype._runHooks = function _runHooks(when, action) { | ||
var _this4 = this; | ||
var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; | ||
var hooks = this._getHooks(when, action); | ||
let hooks = this._getHooks(when, action); | ||
// skip hooks | ||
var skip = options.skip; | ||
let skip = options.skip; | ||
if (skip) { | ||
if (is.string(skip)) skip = [skip]; | ||
if (is.string(skip)) { | ||
skip = [skip]; | ||
} | ||
hooks = hooks.filter(function (fn) { | ||
@@ -468,10 +520,11 @@ return skip.indexOf(fn.name) === -1; | ||
} | ||
var middleware = []; | ||
let middleware = []; | ||
let self = this; | ||
// insert a rollback fn | ||
// before each hook | ||
hooks.forEach(function (fn) { | ||
var rollback = _this4._rollbackFor(fn.name); | ||
let rollback = self._rollbackFor(fn.name); | ||
middleware.push(rollback, fn); | ||
@@ -481,4 +534,5 @@ }); | ||
return compose(middleware).call(this); | ||
}; | ||
} | ||
/** | ||
@@ -489,15 +543,16 @@ * Get hooks for a given operation | ||
*/ | ||
Model.prototype._getHooks = function _getHooks(when, action) { | ||
var hooks = this._hooks[when][action] || []; | ||
_getHooks (when, action) { | ||
let hooks = this._hooks[when][action] || []; | ||
// if create or update hooks requested | ||
// prepend save hooks also | ||
if (action === 'create' || action === 'update') { | ||
hooks.push.apply(hooks, this._hooks[when]['save']); | ||
hooks.push.apply(hooks, this._hooks[when].save); | ||
} | ||
return hooks; | ||
}; | ||
} | ||
/** | ||
@@ -509,18 +564,18 @@ * Save a model | ||
*/ | ||
Model.prototype.save = function* save(options) { | ||
var _this5 = this; | ||
* save (options) { | ||
// set default values if needed | ||
this._setDefaults(); | ||
var id = this.get('_id'); | ||
var fn = id ? this.update : this.create; | ||
let id = this.get('_id'); | ||
let fn = id ? this.update : this.create; | ||
// revert populated documents to _id's | ||
var populate = this.options.populate || emptyObject; | ||
var keys = Object.keys(populate); | ||
let populate = this.options.populate || emptyObject; | ||
let keys = Object.keys(populate); | ||
let self = this; | ||
keys.forEach(function (key) { | ||
var value = _this5.get(key); | ||
let value = self.get(key); | ||
@@ -535,8 +590,9 @@ if (is.array(value)) { | ||
_this5.set(key, value); | ||
self.set(key, value); | ||
}); | ||
return yield fn.call(this, options); | ||
}; | ||
} | ||
/** | ||
@@ -547,11 +603,12 @@ * Create a model | ||
*/ | ||
* create (options) { | ||
let collection = this._collection; | ||
let attrs = this.attributes; | ||
Model.prototype.create = function* create(options) { | ||
var collection = this._collection; | ||
var attrs = this.attributes; | ||
let date = new Date; | ||
var date = new Date(); | ||
this.set({ | ||
created_at: date, | ||
updated_at: date | ||
'created_at': date, | ||
'updated_at': date | ||
}); | ||
@@ -561,3 +618,4 @@ | ||
var doc = yield collection.insert(attrs); | ||
let doc = yield collection.insert(attrs); | ||
this.set('_id', doc._id); | ||
@@ -568,4 +626,5 @@ | ||
return this; | ||
}; | ||
} | ||
/** | ||
@@ -576,9 +635,9 @@ * Update a model | ||
*/ | ||
* update (options) { | ||
let collection = this._collection; | ||
let attrs = this.attributes; | ||
Model.prototype.update = function* update(options) { | ||
var collection = this._collection; | ||
var attrs = this.attributes; | ||
this.set('updated_at', new Date); | ||
this.set('updated_at', new Date()); | ||
yield* this._runHooks('before', 'update', options); | ||
@@ -589,4 +648,5 @@ yield collection.updateById(attrs._id, attrs); | ||
return this; | ||
}; | ||
} | ||
/** | ||
@@ -597,6 +657,6 @@ * Remove a model | ||
*/ | ||
* remove (options) { | ||
let collection = this._collection; | ||
Model.prototype.remove = function* remove(options) { | ||
var collection = this._collection; | ||
yield* this._runHooks('before', 'remove', options); | ||
@@ -607,4 +667,5 @@ yield collection.remove({ _id: this.get('_id') }); | ||
return this; | ||
}; | ||
} | ||
/** | ||
@@ -617,8 +678,6 @@ * Atomically increment a model property | ||
*/ | ||
* inc (props, options) { | ||
let id = this.get('_id'); | ||
Model.prototype.inc = function* inc(props, options) { | ||
var _this6 = this; | ||
var id = this.get('_id'); | ||
if (!id) { | ||
@@ -628,4 +687,4 @@ throw new Error('Can\'t atomically increment a property of unsaved document.'); | ||
var collection = this._collection; | ||
let collection = this._collection; | ||
yield* this._runHooks('before', 'update', options); | ||
@@ -640,5 +699,7 @@ | ||
// the model from a database | ||
let self = this; | ||
Object.keys(props).forEach(function (key) { | ||
// get current value | ||
var value = _this6.get(key); | ||
let value = self.get(key); | ||
@@ -649,3 +710,3 @@ // perform increment | ||
// save | ||
_this6.set(key, value); | ||
self.set(key, value); | ||
}); | ||
@@ -656,4 +717,5 @@ | ||
return this; | ||
}; | ||
} | ||
/** | ||
@@ -664,4 +726,37 @@ * Get database for a model | ||
*/ | ||
static get _db () { | ||
// support for multiple connections | ||
// if model has a custom database assigned | ||
// use it, otherwise use the default | ||
return this.prototype.db || Mongorito.db; | ||
} | ||
/** | ||
* Get collection for a model | ||
* | ||
* @api private | ||
*/ | ||
static get _collection () { | ||
if (is.string(this.prototype.collection)) { | ||
return Mongorito._collection(this._db, this.prototype.collection); | ||
} | ||
// get collection name | ||
// from the "collection" property | ||
// or generate the default one | ||
let defaultName = pluralize(this.name).toLowerCase(); | ||
let name = result(this.prototype, 'collection', defaultName); | ||
// save collection name | ||
// to avoid the same check in future | ||
this.prototype.collection = name; | ||
return Mongorito._collection(this._db, name); | ||
} | ||
/** | ||
* Find documents | ||
@@ -672,6 +767,8 @@ * | ||
*/ | ||
static find (query) { | ||
// collection, model | ||
return new Query(this._collection, this).find(query); | ||
} | ||
Model.find = function find(query) { | ||
return new Query(this._collection, this).find(query); // collection, model | ||
}; | ||
@@ -684,7 +781,9 @@ /** | ||
*/ | ||
static count (query) { | ||
// collection, model | ||
return new Query(this._collection, this).count(query); | ||
} | ||
Model.count = function count(query) { | ||
return new Query(this._collection, this).count(query); // collection, model | ||
}; | ||
/** | ||
@@ -695,7 +794,8 @@ * Find all documents in a collection | ||
*/ | ||
Model.all = function all() { | ||
static all () { | ||
return this.find(); | ||
}; | ||
} | ||
/** | ||
@@ -707,9 +807,10 @@ * Find one document | ||
*/ | ||
static * findOne (query) { | ||
let docs = yield* this.find(query); | ||
Model.findOne = function* findOne(query) { | ||
var docs = yield* this.find(query); | ||
return docs[0]; | ||
}; | ||
} | ||
/** | ||
@@ -721,7 +822,8 @@ * Find a document by ID | ||
*/ | ||
Model.findById = function findById(id) { | ||
static findById (id) { | ||
return this.findOne({ _id: id }); | ||
}; | ||
} | ||
/** | ||
@@ -733,7 +835,9 @@ * Remove documents | ||
*/ | ||
Model.remove = function remove(query) { | ||
return new Query(this._collection, this).remove(query); // collection, model | ||
}; | ||
static remove (query) { | ||
// collection, model | ||
return new Query(this._collection, this).remove(query); | ||
} | ||
/** | ||
@@ -744,7 +848,8 @@ * Drop collection | ||
*/ | ||
Model.drop = function* drop() { | ||
static * drop () { | ||
yield this._collection.drop(); | ||
}; | ||
} | ||
/** | ||
@@ -756,9 +861,8 @@ * Set up an index | ||
*/ | ||
static * index () { | ||
return yield this._collection.index.apply(this._collection, arguments); | ||
} | ||
Model.index = function* index() { | ||
var _collection2; | ||
return yield (_collection2 = this._collection).index.apply(_collection2, arguments); | ||
}; | ||
/** | ||
@@ -770,90 +874,40 @@ * List all indexes | ||
*/ | ||
Model.indexes = function* indexes() { | ||
static * indexes () { | ||
return yield this._collection.indexes(); | ||
}; | ||
} | ||
} | ||
_createClass(Model, [{ | ||
key: '_collection', | ||
get: function get() { | ||
if (is.string(this.collection)) { | ||
return Mongorito._collection(this._db, this.collection); | ||
} | ||
// get collectio name | ||
// from the "collection" property | ||
// or generate the default one | ||
var defaultName = pluralize(this.constructor.name).toLowerCase(); | ||
var name = result(this, 'collection', defaultName); | ||
// save collection name | ||
// to avoid the same check in future | ||
this.collection = this.constructor.prototype.collection = name; | ||
return Mongorito._collection(this._db, this.collection); | ||
} | ||
/** | ||
* Get database for current model | ||
* | ||
* @api private | ||
*/ | ||
}, { | ||
key: '_db', | ||
get: function get() { | ||
// use either custom database | ||
// specified for this model | ||
// or use a default one | ||
return this.db || Mongorito.db; | ||
} | ||
}], [{ | ||
key: '_db', | ||
get: function get() { | ||
// support for multiple connections | ||
// if model has a custom database assigned | ||
// use it, otherwise use the default | ||
return this.prototype.db || Mongorito.db; | ||
} | ||
/** | ||
* Get collection for a model | ||
* | ||
* @api private | ||
*/ | ||
}, { | ||
key: '_collection', | ||
get: function get() { | ||
if (is.string(this.prototype.collection)) { | ||
return Mongorito._collection(this._db, this.prototype.collection); | ||
} | ||
// get collection name | ||
// from the "collection" property | ||
// or generate the default one | ||
var defaultName = pluralize(this.name).toLowerCase(); | ||
var name = result(this.prototype, 'collection', defaultName); | ||
// save collection name | ||
// to avoid the same check in future | ||
this.prototype.collection = name; | ||
return Mongorito._collection(this._db, name); | ||
} | ||
}]); | ||
return Model; | ||
})() | ||
// Setting up functions that have | ||
// the same implementation | ||
// and act as a bridge to Query | ||
; | ||
const methods = [ | ||
'where', | ||
'limit', | ||
'skip', | ||
'sort', | ||
'exists', | ||
'lt', | ||
'lte', | ||
'gt', | ||
'gte', | ||
'in', | ||
'nin', | ||
'and', | ||
'or', | ||
'ne', | ||
'nor', | ||
'populate', | ||
'matches', | ||
'match', | ||
'include', | ||
'exclude', | ||
'search' | ||
]; | ||
const methods = ['where', 'limit', 'skip', 'sort', 'exists', 'lt', 'lte', 'gt', 'gte', 'in', 'nin', 'and', 'or', 'ne', 'nor', 'populate', 'matches', 'match', 'include', 'exclude', 'search']; | ||
methods.forEach(function (method) { | ||
Model[method] = function () { | ||
var query = new Query(this._collection, this); // collection, model | ||
// collection, model | ||
let query = new Query(this._collection, this); | ||
query[method].apply(query, arguments); | ||
@@ -865,8 +919,3 @@ | ||
/** | ||
* Backwards compatibility for ES5-ish way of defining models | ||
*/ | ||
Model.extend = require('./extend')(Model); | ||
/** | ||
@@ -876,9 +925,9 @@ * Expose Mongorito | ||
var _exports = module.exports = Mongorito; | ||
exports = module.exports = Mongorito; | ||
_exports.Model = Model; | ||
exports.Model = Model; | ||
Object.keys(mongoskin).forEach(function (key) { | ||
if (['connect', 'version', 'db'].indexOf(key) === -1) { | ||
_exports[key] = mongoskin[key]; | ||
exports[key] = mongoskin[key]; | ||
} | ||
@@ -885,0 +934,0 @@ }); |
280
lib/query.js
@@ -0,1 +1,3 @@ | ||
'use strict'; | ||
/** | ||
@@ -5,10 +7,5 @@ * Dependencies | ||
'use strict'; | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | ||
const assign = Object.assign || require('object-assign'); | ||
const is = require('is_js'); | ||
const isObjectID = require('./util').isObjectID; | ||
@@ -19,6 +16,4 @@ /** | ||
var Query = (function () { | ||
function Query(collection, model, key) { | ||
_classCallCheck(this, Query); | ||
class Query { | ||
constructor (collection, model, key) { | ||
this.collection = collection; | ||
@@ -35,2 +30,3 @@ this.model = model; | ||
/** | ||
@@ -43,17 +39,14 @@ * Set "where" condition | ||
*/ | ||
Query.prototype.where = function where(key, value) { | ||
var _this = this; | ||
where (key, value) { | ||
// if object was passed instead of key-value pair | ||
// iterate over that object and call .where(key, value) | ||
if (is.object(key)) { | ||
(function () { | ||
var conditions = key; | ||
var keys = Object.keys(conditions); | ||
let conditions = key; | ||
let keys = Object.keys(conditions); | ||
let self = this; | ||
keys.forEach(function (key) { | ||
_this.where(key, conditions[key]); | ||
}); | ||
})(); | ||
keys.forEach(function (key) { | ||
self.where(key, conditions[key]); | ||
}); | ||
} | ||
@@ -80,4 +73,5 @@ | ||
return this; | ||
}; | ||
} | ||
/** | ||
@@ -90,4 +84,4 @@ * Match documents using $elemMatch | ||
*/ | ||
Query.prototype.matches = function matches(key, value) { | ||
matches (key, value) { | ||
if (this.lastKey) { | ||
@@ -98,12 +92,13 @@ value = key; | ||
} | ||
this.query[key] = { $elemMatch: value }; | ||
return this; | ||
}; | ||
Query.prototype.match = function match() { | ||
} | ||
match () { | ||
return this.matches.apply(this, arguments); | ||
}; | ||
} | ||
/** | ||
@@ -116,32 +111,31 @@ * Include fields in a result | ||
*/ | ||
include (key, value) { | ||
let self = this; | ||
Query.prototype.include = function include(key, value) { | ||
var _this2 = this; | ||
if (is.array(key)) { | ||
var fields = key; | ||
let fields = key; | ||
fields.forEach(function (key) { | ||
_this2.include(key); | ||
self.include(key); | ||
}); | ||
} | ||
if (is.object(key)) { | ||
(function () { | ||
var fields = key; | ||
var keys = Object.keys(fields); | ||
keys.forEach(function (key) { | ||
_this2.include(key, fields[key]); | ||
}); | ||
})(); | ||
let fields = key; | ||
let keys = Object.keys(fields); | ||
keys.forEach(function (key) { | ||
self.include(key, fields[key]); | ||
}); | ||
} | ||
if (is.string(key)) { | ||
this.options.fields[key] = value == undefined ? 1 : value; | ||
} | ||
return this; | ||
}; | ||
} | ||
/** | ||
@@ -154,32 +148,31 @@ * Exclude fields from result | ||
*/ | ||
exclude (key, value) { | ||
let self = this; | ||
Query.prototype.exclude = function exclude(key, value) { | ||
var _this3 = this; | ||
if (is.array(key)) { | ||
var fields = key; | ||
let fields = key; | ||
fields.forEach(function (key) { | ||
_this3.exclude(key); | ||
self.exclude(key); | ||
}); | ||
} | ||
if (is.object(key)) { | ||
(function () { | ||
var fields = key; | ||
var keys = Object.keys(fields); | ||
keys.forEach(function (key) { | ||
_this3.exclude(key, fields[key]); | ||
}); | ||
})(); | ||
let fields = key; | ||
let keys = Object.keys(fields); | ||
keys.forEach(function (key) { | ||
self.exclude(key, fields[key]); | ||
}); | ||
} | ||
if (is.string(key)) { | ||
this.options.fields[key] = value == undefined ? 0 : value; | ||
} | ||
return this; | ||
}; | ||
} | ||
/** | ||
@@ -191,4 +184,4 @@ * Search using text index | ||
*/ | ||
Query.prototype.search = function search(text) { | ||
search (text) { | ||
this.where({ | ||
@@ -199,6 +192,7 @@ '$text': { | ||
}); | ||
return this; | ||
}; | ||
} | ||
/** | ||
@@ -210,9 +204,10 @@ * Set query limit | ||
*/ | ||
limit (limit) { | ||
this.options.limit = limit; | ||
Query.prototype.limit = function limit(_limit) { | ||
this.options.limit = _limit; | ||
return this; | ||
}; | ||
} | ||
/** | ||
@@ -224,9 +219,10 @@ * Set query skip | ||
*/ | ||
skip (skip) { | ||
this.options.skip = skip; | ||
Query.prototype.skip = function skip(_skip) { | ||
this.options.skip = _skip; | ||
return this; | ||
}; | ||
} | ||
/** | ||
@@ -240,8 +236,8 @@ * Sort query results | ||
*/ | ||
Query.prototype.sort = function sort(key, value) { | ||
sort (key, value) { | ||
if (is.object(key)) { | ||
assign(this.options.sort, key); | ||
} | ||
if (is.string(key) && value) { | ||
@@ -252,4 +248,5 @@ this.options.sort[key] = value; | ||
return this; | ||
}; | ||
} | ||
/** | ||
@@ -262,5 +259,6 @@ * Same as .where(), only less flexible | ||
*/ | ||
equals (value) { | ||
let key = this.lastKey; | ||
Query.prototype.equals = function equals(value) { | ||
var key = this.lastKey; | ||
this.lastKey = null; | ||
@@ -271,4 +269,5 @@ | ||
return this; | ||
}; | ||
} | ||
/** | ||
@@ -281,6 +280,6 @@ * Set property that must or mustn't exist in resulting docs | ||
*/ | ||
Query.prototype.exists = function exists(key, _exists) { | ||
exists (key, exists) { | ||
if (this.lastKey) { | ||
_exists = key; | ||
exists = key; | ||
key = this.lastKey; | ||
@@ -290,7 +289,8 @@ this.lastKey = null; | ||
this.query[key] = { $exists: _exists || true }; | ||
this.query[key] = { $exists: exists || true }; | ||
return this; | ||
}; | ||
} | ||
/** | ||
@@ -304,9 +304,10 @@ * Query population | ||
*/ | ||
Query.prototype.populate = function populate(key, model) { | ||
populate (key, model) { | ||
this.options.populate[key] = model; | ||
return this; | ||
}; | ||
} | ||
/** | ||
@@ -318,9 +319,9 @@ * Count documents | ||
*/ | ||
Query.prototype.count = function* count(query) { | ||
* count (query) { | ||
this.where(query); | ||
return yield this.collection.count(this.query); | ||
}; | ||
} | ||
/** | ||
@@ -333,7 +334,7 @@ * Find documents | ||
Query.prototype.find = function* find(query, options) { | ||
* find (query, options) { | ||
this.where(query); | ||
var model = this.model; | ||
let Model = this.model; | ||
// query options | ||
@@ -343,20 +344,20 @@ options = assign({}, this.options, options); | ||
// fields to populate | ||
var populate = Object.keys(options.populate); | ||
let populate = Object.keys(options.populate); | ||
// find | ||
var docs = yield this.collection.find(this.query, options); | ||
let docs = yield this.collection.find(this.query, options); | ||
let i = 0; | ||
let doc; | ||
var i = 0; | ||
var doc = undefined; | ||
while (doc = docs[i++]) { | ||
// options.populate is a key-model pair object | ||
var j = 0; | ||
var key = undefined; | ||
let j = 0; | ||
let key; | ||
while (key = populate[j++]) { | ||
// model to use when populating the field | ||
var childModel = options.populate[key]; | ||
let childModel = options.populate[key]; | ||
var value = doc[key]; | ||
let value = doc[key]; | ||
@@ -377,3 +378,3 @@ // if value is an array of IDs, loop through it | ||
// index - 1, because index here is already an index of the next document | ||
docs[i - 1] = new model(doc, { | ||
docs[i - 1] = new Model(doc, { | ||
populate: options.populate | ||
@@ -384,4 +385,5 @@ }); | ||
return docs; | ||
}; | ||
} | ||
/** | ||
@@ -393,9 +395,10 @@ * Find one document | ||
*/ | ||
* findOne (query) { | ||
let docs = yield this.find(query); | ||
Query.prototype.findOne = function* findOne(query) { | ||
var docs = yield this.find(query); | ||
return docs[0]; | ||
}; | ||
} | ||
/** | ||
@@ -408,17 +411,21 @@ * Remove documents | ||
Query.prototype.remove = function* remove(query) { | ||
* remove (query) { | ||
this.where(query); | ||
return yield this.collection.remove(this.query, this.options); | ||
}; | ||
} | ||
} | ||
return Query; | ||
})() | ||
// Setting up functions that | ||
// have the same implementation | ||
; | ||
const methods = [ | ||
'lt', | ||
'lte', | ||
'gt', | ||
'gte', | ||
'in', | ||
'nin', | ||
'ne' | ||
]; | ||
const methods = ['lt', 'lte', 'gt', 'gte', 'in', 'nin', 'ne']; | ||
methods.forEach(function (method) { | ||
@@ -434,8 +441,9 @@ Query.prototype[method] = function (key, value) { | ||
let operator = '$' + method; | ||
if (!value) { | ||
this.query['$' + method] = key; | ||
this.query[operator] = key; | ||
} else { | ||
var _query$key; | ||
this.query[key] = (_query$key = {}, _query$key['$' + method] = value, _query$key); | ||
this.query[key] = {}; | ||
this.query[key][operator] = value; | ||
} | ||
@@ -450,5 +458,6 @@ | ||
Query.prototype[method] = function () { | ||
var args = is.array(arguments[0]) ? arguments[0] : Array.from(arguments); | ||
let args = is.array(arguments[0]) ? arguments[0] : Array.prototype.slice.call(arguments); | ||
let operator = '$' + method; | ||
this.query['$' + method] = args; | ||
this.query[operator] = args; | ||
@@ -459,2 +468,3 @@ return this; | ||
/** | ||
@@ -461,0 +471,0 @@ * Expose Query |
@@ -0,1 +1,3 @@ | ||
'use strict'; | ||
/** | ||
@@ -5,6 +7,5 @@ * Dependencies | ||
'use strict'; | ||
const ObjectID = require('monk/node_modules/mongoskin').ObjectID; | ||
/** | ||
@@ -16,2 +17,3 @@ * Expose utilities | ||
/** | ||
@@ -21,4 +23,4 @@ * Utilities | ||
function isObjectID(value) { | ||
return !!(value && ObjectID === value.constructor); | ||
function isObjectID (value) { | ||
return !!(value && value.constructor === ObjectID); | ||
} |
{ | ||
"name": "mongorito", | ||
"version": "1.3.4", | ||
"version": "1.3.6", | ||
"description": "ES6 generator-based MongoDB ODM. It rocks.", | ||
@@ -14,2 +14,3 @@ "author": "Vadim Demedes <vdemedes@gmail.com>", | ||
"lodash.result": "^3.1.2", | ||
"mongodb": "^1.4.39", | ||
"monk": "^1.0.1", | ||
@@ -21,8 +22,8 @@ "object-assign": "^3.0.0", | ||
"devDependencies": { | ||
"babel": "^5.8.3", | ||
"chai": "^3.0.0", | ||
"chance": "^0.7.6", | ||
"istanbul-harmony": "^0.3.12", | ||
"make-lint-es6": "^1.0.3", | ||
"mocha": "^2.2.5", | ||
"babel": "^5.8.23", | ||
"chai": "^3.3.0", | ||
"chance": "^0.7.7", | ||
"istanbul-harmony": "^0.3.16", | ||
"make-lint": "vdemedes/make-lint", | ||
"mocha": "^2.3.3", | ||
"mocha-generators": "^1.1.1" | ||
@@ -37,3 +38,3 @@ }, | ||
"test": "make test", | ||
"postinstall": "npm uninstall monk/node_modules/mongodb/node_modules/bson" | ||
"postinstall": "cd node_modules/monk/node_modules/mongodb && npm uninstall bson && cd ../../../; cd node_modules/mongodb && npm uninstall bson" | ||
}, | ||
@@ -40,0 +41,0 @@ "repository": { |
@@ -1,15 +0,23 @@ | ||
# Mongorito [![Circle CI](https://circleci.com/gh/vdemedes/mongorito.svg?style=svg)](https://circleci.com/gh/vdemedes/mongorito) | ||
# Mongorito [![Build Status](https://travis-ci.org/vdemedes/mongorito.svg?branch=master)](https://travis-ci.org/vdemedes/mongorito) | ||
Awesome ES6 generator-based MongoDB ODM for Node.js v0.11.x (or newer) and io.js. | ||
Awesome ES6 generator-based MongoDB ODM for Node.js v4.x (or newer). | ||
Just take a look on its pretty models and beautiful API. | ||
Uses [monk](https://github.com/Automattic/monk) under the hood. | ||
<h1 align="center"> | ||
<br> | ||
<img width="200" src="media/logo.png"> | ||
<br> | ||
<br> | ||
</h1> | ||
### Features | ||
- Based on ES6 generators, which means **no callbacks** | ||
- Common, established API you've already used to | ||
- Established API you've already used to | ||
- Hooks (before:save, around:create, after:remove, etc) | ||
- Very simple and easy-to-understand implementation | ||
- Fully covered by tests | ||
- Using this module results in a beautiful code | ||
@@ -20,21 +28,14 @@ | ||
``` | ||
npm install mongorito --save | ||
$ npm install mongorito --save | ||
``` | ||
**Warning**: You should have Node.js v0.11.x or io.js installed (or newer). Run node with `--harmony` option (not applicable to io.js): | ||
**Note**: In order for the following examples to work, you need to use [co](https://github.com/tj/co) to run generators. | ||
``` | ||
node --harmony script.js | ||
``` | ||
**Note**: In order for the following examples to work, you need use something like [co](https://github.com/tj/co) to run generators. | ||
**Another note**: If you want to use ES6 classes (like in the following examples), use [babel](https://github.com/babel/babel). If not, there is an alternative API left from previous versions of Mongorito. | ||
### Usage | ||
```js | ||
const Mongorito = require('mongorito'); | ||
const Model = Mongorito.Model; | ||
### Overview | ||
```javascript | ||
var Mongorito = require('mongorito'); | ||
var Model = Mongorito.Model; | ||
// connect to localhost/blog | ||
@@ -50,4 +51,4 @@ Mongorito.connect('localhost/blog'); | ||
// create new Post document | ||
var post = new Post({ | ||
// create and save new Post document | ||
let post = new Post({ | ||
title: 'Node.js with --harmony rocks!', | ||
@@ -60,4 +61,2 @@ body: 'Long post body', | ||
// create | ||
yield post.save(); | ||
@@ -70,12 +69,6 @@ | ||
// update | ||
yield post.save(); | ||
// find some posts | ||
var posts; | ||
// find posts where body equals "Long post body" | ||
posts = yield Post.where('body', 'Long post body').find(); | ||
let posts = yield Post.where('body', 'Long post body').find(); | ||
@@ -87,12 +80,9 @@ // find posts where author's name equals "John Doe" | ||
posts = yield Post.where('title', /^node/i).find(); | ||
// disconnect | ||
Mongorito.disconnect(); | ||
``` | ||
### Getting Started | ||
### API | ||
Check out [Getting Started](http://mongorito.com/guides/getting-started) guide on [http://mongorito.com](http://mongorito.com). | ||
There are more guides available to learn more. | ||
@@ -102,8 +92,6 @@ | ||
[![Circle CI](https://circleci.com/gh/vdemedes/mongorito.svg?style=svg)](https://circleci.com/gh/vdemedes/mongorito) | ||
[![Build Status](https://travis-ci.org/vdemedes/mongorito.svg?branch=master)](https://travis-ci.org/vdemedes/mongorito) | ||
To execute tests run: | ||
``` | ||
npm test | ||
$ make test | ||
``` | ||
@@ -110,0 +98,0 @@ |
Install scripts
Supply chain riskInstall scripts are run when the package is installed. The majority of malware in npm is hidden in install scripts.
Found 1 instance in 1 package
AI-detected potential security risk
Supply chain riskAI has determined that this package may contain potential security issues or vulnerabilities.
Found 1 instance in 1 package
Install scripts
Supply chain riskInstall scripts are run when the package is installed. The majority of malware in npm is hidden in install scripts.
Found 1 instance in 1 package
27336
12
6
1015
97
1
+ Addedmongodb@^1.4.39