New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

mongorito

Package Overview
Dependencies
Maintainers
1
Versions
50
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mongorito - npm Package Compare versions

Comparing version 2.2.0 to 3.0.0

lib/action-types.js

18

index.js

@@ -1,1 +0,17 @@

module.exports = require('./lib/mongorito');
'use strict';
const mongodb = require('mongodb');
const Database = require('./lib/database');
const Model = require('./lib/model');
const ActionTypes = require('./lib/action-types');
const x = module.exports = Database;
x.Database = Database;
x.Model = Model;
x.ActionTypes = ActionTypes;
x.Timestamp = mongodb.Timestamp;
x.ObjectId = mongodb.ObjectId;
x.MinKey = mongodb.MinKey;
x.MaxKey = mongodb.MaxKey;
x.DBRef = mongodb.DBRef;
x.Long = mongodb.Long;

563

lib/query.js
'use strict';
/**
* Dependencies
*/
const isObject = require('is-plain-obj');
const queryMethods = require('./query-methods');
const toObjectId = require('../util/to-objectid');
const Promise = require('bluebird');
const assign = require('object-assign');
const is = require('is_js');
/**
* Query
*/
function Query (collection, model, key) {
this.collection = collection;
this.model = model;
this.query = {};
this.options = {
populate: {},
sort: {},
fields: {}
};
this.lastKey = key;
}
/**
* Set "where" condition
*
* @param {String} key - key
* @param {Mixed} value - value
* @api public
*/
Query.prototype.where = function (key, value) {
// if object was passed instead of key-value pair
// iterate over that object and call .where(key, value)
if (is.object(key)) {
let conditions = key;
let keys = Object.keys(conditions);
let self = this;
keys.forEach(function (key) {
self.where(key, conditions[key]);
});
class Query {
constructor(modelClass) {
this.Model = modelClass;
this.query = [];
}
if (is.string(key)) {
// if only one argument was supplied
// save the key in this.lastKey
// for future methods, like .equals()
if (is.undefined(value)) {
this.lastKey = key;
return this;
find(query = {}) {
if (typeof query !== 'undefined' && typeof query !== 'object') {
throw new TypeError(`Expected \`query\` to be object or undefined, got ${typeof query}`);
}
// if value is a regular expression
// use $regex modifier
if (is.regexp(value)) {
value = { $regex: value };
}
this.where(query);
if (is.array(value)) {
value = { $in: value };
}
return this.Model.query('find', this.query)
.then(documents => {
return documents.map(doc => new this.Model(doc));
});
}
this.query[key] = value;
then(...args) {
return this.find(...args);
}
return this;
};
findOne(query = {}) {
if (typeof query !== 'undefined' && typeof query !== 'object') {
throw new TypeError(`Expected \`query\` to be object or undefined, got ${typeof query}`);
}
this.where(query);
/**
* Match documents using $elemMatch
*
* @param {String} key
* @param {Object} value
* @api public
*/
Query.prototype.matches = function (key, value) {
if (this.lastKey) {
value = key;
key = this.lastKey;
this.lastKey = null;
return this.Model.query('findOne', this.query)
.then(doc => doc ? new this.Model(doc) : null);
}
this.query[key] = { $elemMatch: value };
findById(id) {
if (typeof id !== 'object' && typeof id !== 'string') {
throw new TypeError(`Expected \`id\` to be object or string, got ${typeof id}`);
}
return this;
};
this.where('_id', id);
Query.prototype.match = function () {
return this.matches.apply(this, arguments);
};
/**
* Include fields in a result
*
* @param {String} key
* @param {Mixed} value
* @api public
*/
Query.prototype.include = function (key, value) {
let self = this;
if (Array.isArray(key)) {
let fields = key;
fields.forEach(function (key) {
self.include(key);
});
} else if (is.object(key)) {
let fields = key;
let keys = Object.keys(fields);
keys.forEach(function (key) {
self.include(key, fields[key]);
});
return this.Model.query('findOne', this.query)
.then(doc => doc ? new this.Model(doc) : null);
}
if (is.string(key)) {
this.options.fields[key] = value === undefined ? 1 : value;
}
remove(query = {}) {
if (typeof query !== 'undefined' && typeof query !== 'object') {
throw new TypeError(`Expected \`query\` to be object or undefined, got ${typeof query}`);
}
return this;
};
this.where(query);
/**
* Exclude fields from result
*
* @param {String} key
* @param {String} value
* @api public
*/
Query.prototype.exclude = function (key, value) {
let self = this;
if (Array.isArray(key)) {
let fields = key;
fields.forEach(function (key) {
self.exclude(key);
});
} else if (is.object(key)) {
let fields = key;
let keys = Object.keys(fields);
keys.forEach(function (key) {
self.exclude(key, fields[key]);
});
return this.Model.query('remove', this.query);
}
if (is.string(key)) {
this.options.fields[key] = value === undefined ? 0 : value;
}
return this;
};
/**
* Search using text index
*
* @param {String} text
* @api public
*/
Query.prototype.search = function (text) {
this.where({
'$text': {
'$search': text
count(query = {}) {
if (typeof query !== 'undefined' && typeof query !== 'object') {
throw new TypeError(`Expected \`query\` to be object or undefined, got ${typeof query}`);
}
});
return this;
};
this.where(query);
/**
* Get distinct
*
* @param {String} field for distinct
* @param {Object} query - query to filter the results
* @see http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#distinct
* @api public
*/
Query.prototype.distinct = function (field, query) {
let self = this;
this.where(query);
return this.collection.then(function (collection) {
return collection.distinct(field, self.query);
});
};
/**
* Aggregation query
*
* @param {String} pipeline aggregation pipeline
* @param {Object} options - Options to be passed to aggregation pipeline
* @see http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#aggregate
* @api public
*/
Query.prototype.aggregate = function (pipeline) {
return this.collection.then(function (collection) {
let cursor = collection.aggregate(pipeline, { cursor: { batchSize: 1 } });
return cursor
.toArray()
.then(function (docs) {
cursor.close();
return docs;
});
});
};
/**
* Set query limit
*
* @param {Number} limit - limit number
* @api public
*/
Query.prototype.limit = function (limit) {
this.options.limit = limit;
return this;
};
/**
* Set query skip
*
* @param {Number} skip - skip number
* @api public
*/
Query.prototype.skip = function (skip) {
this.options.skip = skip;
return this;
};
/**
* Sort query results
*
* @param {Object} sort - sort params
* @see http://mongodb.github.io/node-mongodb-native/2.0/api/Cursor.html#sort
* @api public
*/
Query.prototype.sort = function (key, value) {
if (is.object(key)) {
assign(this.options.sort, key);
return this.Model.query('count', this.query);
}
if (is.string(key) && value) {
this.options.sort[key] = value;
}
include(field, value = 1) {
if (!Array.isArray(field) && typeof field !== 'object' && typeof field !== 'string') {
throw new TypeError(`Expected \`field\` to be array, object or string, got ${typeof field}`);
}
return this;
};
if (typeof value !== 'number') {
throw new TypeError(`Expected \`value\` to be number, got ${typeof value}`);
}
if (Array.isArray(field)) {
field.forEach(field => this.include(field));
return this;
}
/**
* Same as .where(), only less flexible
*
* @param {String} key - key
* @param {Mixed} value - value
* @api public
*/
const select = isObject(field) ? field : {[field]: value};
this.query.push(['select', select]);
Query.prototype.equals = function (value) {
let key = this.lastKey;
this.lastKey = null;
this.query[key] = value;
return this;
};
/**
* Set property that must or mustn't exist in resulting docs
*
* @param {String} key - key
* @param {Boolean} exists - exists or not
* @api public
*/
Query.prototype.exists = function (key, exists) {
if (this.lastKey) {
exists = key;
key = this.lastKey;
this.lastKey = null;
return this;
}
this.query[key] = { $exists: (exists === undefined ? true : exists) };
exclude(field, value = 0) {
if (!Array.isArray(field) && typeof field !== 'object' && typeof field !== 'string') {
throw new TypeError(`Expected \`field\` to be array, object or string, got ${typeof field}`);
}
return this;
};
if (typeof value !== 'number') {
throw new TypeError(`Expected \`value\` to be number, got ${typeof value}`);
}
/**
* Query population
*
* @param {String} key - key
* @param {Model} model - model to populate with
* @see http://mongorito.com/guides/query-population/
* @api public
*/
Query.prototype.populate = function (key, model) {
this.options.populate[key] = model;
return this;
};
/**
* Count documents
*
* @param {Object} query - find conditions, same as this.where()
* @api public
*/
Query.prototype.count = function (query) {
let self = this;
this.where(query);
return this.collection.then(function (collection) {
return collection.count(self.query);
});
};
/**
* Find documents
*
* @param {Object} query - find conditions, same as this.where()
* @api public
*/
Query.prototype.find = function (query, options) {
let Model = this.model;
query = assign({}, this.query, query);
// query options
options = assign({}, this.options, options);
// fields to populate
let populate = Object.keys(options.populate);
// ensure _id is ObjectId
if (query._id) {
if (is.object(query._id)) {
if (query._id.$in) {
let convertedIds = [];
query._id.$in.forEach(function (id) {
convertedIds.push(toObjectId(id));
});
query._id.$in = convertedIds;
}
} else {
query._id = toObjectId(query._id);
if (Array.isArray(field)) {
field.forEach(field => this.exclude(field));
return this;
}
}
// find
return this.collection
.then(function (collection) {
let cursor = collection.find(query, options);
const select = isObject(field) ? field : {[field]: value};
this.query.push(['select', select]);
return cursor
.toArray()
.then(function (docs) {
cursor.close();
return docs;
});
})
.map(function (doc) {
return Promise.each(populate, function (key) {
let childModel = options.populate[key];
let idsArray = doc[key];
let promise = childModel.findById(idsArray);
return promise.then(function (subdocs) {
// reorder the received documents as ordered in the IDs Array
let orderedDocuments = idsArray.slice();
subdocs.map(doc => {
let id = toObjectId(doc.get('_id'));
for (let index in idsArray) {
if (idsArray[index].equals && idsArray[index].equals(id)) {
orderedDocuments[index] = doc;
}
}
});
doc[key] = orderedDocuments;
});
}).then(function () {
return new Model(doc, {
populate: options.populate
});
});
});
};
/**
* Find one document
*
* @param {Object} query - find conditions, same as this.where()
* @api public
*/
Query.prototype.findOne = function (query) {
return this.find(query)
.then(function (docs) {
return docs[0];
});
};
/**
* Find documents by ID
*
* @param {ObjectID} id - document id or Array of document ids
* @api public
*/
Query.prototype.findById = function (id) {
if (Array.isArray(id)) {
let ids = id.map(id => toObjectId(id));
return this.find({ _id: { $in: ids } });
return this;
}
return this.findOne({ _id: toObjectId(id) });
};
sort(field, value = 'desc') {
if (!Array.isArray(field) && typeof field !== 'object' && typeof field !== 'string') {
throw new TypeError(`Expected \`field\` to be array, object or string, got ${typeof field}`);
}
/**
* Remove documents
*
* @param {Object} query - remove conditions, same as this.where()
* @api public
*/
if (typeof value !== 'string' && typeof value !== 'number') {
throw new TypeError(`Expected \`value\` to be string or number, got ${typeof value}`);
}
Query.prototype.remove = function (query) {
let self = this;
this.where(query);
return this.collection.then(function (collection) {
return collection.remove(self.query, self.options);
});
};
// Setting up functions that
// have the same implementation
const methods = [
'lt',
'lte',
'gt',
'gte',
'in',
'nin',
'ne'
];
methods.forEach(function (method) {
Query.prototype[method] = function (key, value) {
// if .where() was called with one argument
// key was already set in this.lastKey
if (this.lastKey) {
value = key;
key = this.lastKey;
this.lastKey = null;
if (Array.isArray(field)) {
field.forEach(field => this.sort(field));
return this;
}
let operator = '$' + method;
let hasValue = value !== undefined;
const sort = isObject(field) ? field : {[field]: value};
this.query.push(['sort', sort]);
if (hasValue) {
this.query[key] = {};
this.query[key][operator] = value;
} else {
this.query[operator] = key;
}
return this;
};
});
}
}
// or, nor and and share the same imlpementation
['or', 'nor', 'and'].forEach(function (method) {
Query.prototype[method] = function () {
let args = Array.isArray(arguments[0]) ? arguments[0] : Array.prototype.slice.call(arguments);
let operator = '$' + method;
this.query[operator] = args;
queryMethods.forEach(name => {
Query.prototype[name] = function (...args) {
this.query.push([name, args]);
return this;

@@ -525,7 +139,2 @@ };

/**
* Expose Query
*/
module.exports = Query;
{
"name": "mongorito",
"version": "2.2.0",
"description": "ES6 generator-based MongoDB ODM. It rocks.",
"version": "3.0.0",
"description": "ES6 generator-based MongoDB ODM.",
"author": "Vadim Demedes <vdemedes@gmail.com>",
"dependencies": {
"bluebird": "^3.3.1",
"class-extend": "^0.1.2",
"clone": "^1.0.2",
"co": "^4.6.0",
"get-value": "^2.0.3",
"is-generator-fn": "^1.0.0",
"is_js": "^0.7.4",
"lodash.result": "^4.2.0",
"mongodb": "^2.0.48",
"object-assign": "^4.0.1",
"pluralize": "^1.2.1",
"set-value": "^0.2.0"
},
"devDependencies": {
"ava": "^0.12.0",
"chance": "^0.8.0",
"coveralls": "^2.11.4",
"eslint-config-vdemedes": "^1.0.2",
"nyc": "^5.0.0",
"xo": "^0.12.1"
},
"repository": "vdemedes/mongorito",
"keywords": [
"mongo",
"mongodb",
"odm"
],
"license": "MIT",
"files": [

@@ -37,29 +22,33 @@ "index.js",

},
"repository": "vdemedes/mongorito",
"keywords": [
"mongo",
"mongodb",
"co-mongo",
"co-mongodb",
"orm",
"odm",
"es6"
],
"license": "MIT",
"engines": {
"node": ">= 6"
},
"dependencies": {
"arrify": "^1.0.1",
"dot-prop": "^4.0.0",
"is-plain-obj": "^1.1.0",
"lodash.merge": "^4.6.0",
"lodash.omit": "^4.5.0",
"lodash.result": "^4.5.2",
"map-obj": "^2.0.0",
"mongodb": "^2.2.9",
"mquery": "^1.11.0",
"pluralize": "^3.0.0",
"redux": "^3.6.0"
},
"devDependencies": {
"ava": "^0.16.0",
"chance": "^1.0.4",
"coveralls": "^2.11.12",
"nyc": "^8.1.0",
"sinon": "^2.1.0",
"xo": "^0.17.0"
},
"xo": {
"extends": "vdemedes",
"esnext": true,
"env": [
"node",
"mocha"
],
"ignore": [
"examples/*.js"
],
"rules": {
"prefer-arrow-callback": 0,
"prefer-spread": 0,
"no-use-extend-native/no-use-extend-native": 0
}
"env": "node"
},
"ava": {
"serial": true,
"failFast": true
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc