vitamin
Version:
Data Mapper library for Node.js applications
450 lines (359 loc) • 10.1 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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; }; }();
var _underscore = require('underscore');
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/**
* @class Collection
*/
var _class = function () {
/**
* Collection constructor
*
* @param {Array} models
* @constructor
*/
function _class() {
var models = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
_classCallCheck(this, _class);
this.models = models;
}
/**
* Get the length of the collection
*
* @var int
*/
_createClass(_class, [{
key: 'isEmpty',
/**
* Determine if the collection is empty
*
* @return boolean
*/
value: function isEmpty() {
return this.length === 0;
}
/**
* Set the collection mapper
*
* @param {Mapper} mapper
* @return this collection
*/
}, {
key: 'setMapper',
value: function setMapper(mapper) {
this.mapper = mapper;
return this;
}
/**
* Get the collection as an array of plain objects
*
* @return array
*/
}, {
key: 'toJSON',
value: function toJSON() {
return (0, _underscore.invoke)(this.models, 'toJSON');
}
/**
* Get all items as a plain array
*
* @return array
*/
}, {
key: 'toArray',
value: function toArray() {
return this.models.slice();
}
/**
* Get an array with the values of the given key
*
* @param {String} key
* @return array
*/
}, {
key: 'pluck',
value: function pluck(key) {
return (0, _underscore.invoke)(this.models, 'get', key);
}
/**
* Get the model at the given position
*
* @param {Integer} position
* @return model instance
*/
}, {
key: 'at',
value: function at(position) {
return this.models[position];
}
/**
* Run a map callback over each model
*
* @param {Function} fn
* @param {Object} context
* @return a new collection
*/
}, {
key: 'map',
value: function map(fn) {
var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
this.ensureMapper();
return this.mapper.newCollection(this.models.map(fn, context));
}
/**
* Reduce the collection to a single value
*
* @param {Function} fn
* @param {Any} initial
* @param {Object} context
* @return any
*/
}, {
key: 'reduce',
value: function reduce(fn) {
var initial = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
return (0, _underscore.reduce)(this.models, fn, initial, context);
}
/**
* Execute a callback over each model
*
* @param {Function} fn
* @param {Object} context
* @return this collection
*/
}, {
key: 'forEach',
value: function forEach(fn) {
var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
this.models.forEach(fn, context);
return this;
}
/**
* Get the primary keys of the collection models
*
* @return array
*/
}, {
key: 'keys',
value: function keys() {
return (0, _underscore.invoke)(this.models, 'getId');
}
/**
* Get the first model, or undefined if the collection is empty
*
* @return Model
*/
}, {
key: 'first',
value: function first() {
return (0, _underscore.first)(this.models);
}
/**
* Get the last model, or undefined if the collection is empty
*
* @return Model
*/
}, {
key: 'last',
value: function last() {
return (0, _underscore.last)(this.models);
}
/**
* Group the collection by field or using a callback
*
* @param {String|Function} iteratee
* @param {Object} context
* @return plain object
*/
}, {
key: 'groupBy',
value: function groupBy(iteratee) {
var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
if ((0, _underscore.isString)(iteratee)) {
(function () {
var key = iteratee;
iteratee = function iteratee(model) {
return model.get(key);
};
})();
}
return (0, _underscore.groupBy)(this.models, iteratee, context);
}
/**
* Key the collection by field or using a callback
*
* @param {String|Function} iteratee
* @param {Object} context
* @return plain object
*/
}, {
key: 'keyBy',
value: function keyBy(iteratee) {
var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
if ((0, _underscore.isString)(iteratee)) {
(function () {
var key = iteratee;
iteratee = function iteratee(model) {
return model.get(key);
};
})();
}
return (0, _underscore.indexBy)(this.models, iteratee, context);
}
/**
* Find a model in the collection by key
*
* @param {String} key
* @return model
*/
}, {
key: 'find',
value: function find(id) {
return (0, _underscore.find)(this.models, function (model) {
return model.getId() == id;
});
}
/**
* Run a filter over each of the models
*
* @param {Function} fn
* @param {Object} context
* @return a new collection
*/
}, {
key: 'filter',
value: function filter(fn) {
var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
this.ensureMapper();
return this.mapper.newCollection((0, _underscore.filter)(this.models, fn, context));
}
/**
* Filter items by the given key value pair
*
* @param {String|Object} key
* @param {Any} value
* @return a new collection
*/
}, {
key: 'where',
value: function where(key) {
var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
function iteratee(model) {
if ((0, _underscore.isObject)(key)) {
var keys = Object.keys(key);
for (var i = 0; i < keys.length; i++) {
var attr = keys[i];
if (model.get(attr) != key[attr]) return false;
}
return true;
}
return model.get(key) == value;
}
return this.filter(iteratee);
}
/**
* Determine if a key/value pair exists in the collection
*
* @param {String|Object|Function} key
* @param {Any} value
* @return boolean
*/
}, {
key: 'contains',
value: function contains(key) {
var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
if ((0, _underscore.isFunction)(key)) return !this.filter(key).isEmpty();
return !this.where(key, value).isEmpty();
}
/**
* Save the collection models in the database
*
* @param {Array} returning
* @return promise
*/
}, {
key: 'save',
value: function save() {
var returning = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['*'];
this.ensureMapper();
return this.mapper.saveMany(this.models, returning).return(this);
}
/**
* Delete the collection models from the database
*
* @return promise
*/
}, {
key: 'destroy',
value: function destroy() {
this.ensureMapper();
return this.mapper.destroyMany(this.models).return(this);
}
/**
* Touch the collection models
*
* @return promise
*/
}, {
key: 'touch',
value: function touch() {
this.ensureMapper();
return this.mapper.touchMany(this.models).return(this);
}
/**
* Trigger an event with arguments
*
* @param {String} event
* @param {Array} args
* @return promise
*/
}, {
key: 'emit',
value: function emit(event) {
var _mapper;
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
this.ensureMapper();
return (_mapper = this.mapper).emit.apply(_mapper, arguments);
}
/**
* Load a set of relationships onto the collection
*
* @param {Array} relations
* @return promise
*/
}, {
key: 'load',
value: function load() {
var _mapper2;
this.ensureMapper();
for (var _len2 = arguments.length, relations = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
relations[_key2] = arguments[_key2];
}
return (_mapper2 = this.mapper).load.apply(_mapper2, [this.models].concat(relations)).return(this);
}
/**
* Throw an Error if the mapper is not defined
*
* @throws ReferenceError
* @private
*/
}, {
key: 'ensureMapper',
value: function ensureMapper() {
if (!this.mapper) throw new ReferenceError("Collection mapper is not defined");
}
}, {
key: 'length',
get: function get() {
return this.models.length;
}
}]);
return _class;
}();
exports.default = _class;