Comparing version 4.1.0 to 5.0.0
@@ -0,1 +1,6 @@ | ||
5.0.0 / 2017-05-21 | ||
================== | ||
- Remove deprecated methods | ||
- Middleware architecture! See https://automattic.github.io/monk/docs/middlewares.html for more information | ||
4.1.0 / 2017-05-20 | ||
@@ -2,0 +7,0 @@ ================== |
@@ -1,46 +0,15 @@ | ||
/* | ||
* Module dependencies. | ||
*/ | ||
var applyMiddlewares = require('./applyMiddlewares') | ||
var util = require('./util') | ||
var debug = require('debug')('monk:queries') | ||
function thenFn (fn) { | ||
return function (res) { | ||
if (fn && typeof fn === 'function') { | ||
fn(null, res) | ||
} | ||
return res | ||
} | ||
} | ||
function catchFn (fn) { | ||
return function (err) { | ||
if (fn && typeof fn === 'function') { | ||
return fn(err) | ||
} | ||
throw err | ||
} | ||
} | ||
/* | ||
* Module exports | ||
*/ | ||
module.exports = Collection | ||
/** | ||
* Mongo Collection. | ||
* | ||
*/ | ||
function Collection (manager, name, options) { | ||
this.manager = manager | ||
this.name = name | ||
this.options = options || {} | ||
this.options = options | ||
delete this.options.cache | ||
this.middlewares = this.options.middlewares || [] | ||
delete this.options.middlewares | ||
this.oid = this.id | ||
this.opts = this.opts.bind(this) | ||
delete this.options.plugins | ||
this.createIndex = this.createIndex.bind(this) | ||
@@ -52,10 +21,6 @@ this.index = this.ensureIndex = this.ensureIndex.bind(this) | ||
this.update = this.update.bind(this) | ||
this.updateById = this.updateById.bind(this) | ||
this.remove = this.remove.bind(this) | ||
this.removeById = this.removeById.bind(this) | ||
this.findAndModify = this.findAndModify.bind(this) | ||
this.findOneAndUpdate = this.findOneAndUpdate.bind(this) | ||
this.findOneAndDelete = this.findOneAndDelete.bind(this) | ||
this.insert = this.insert.bind(this) | ||
this.findById = this.findById.bind(this) | ||
this.find = this.find.bind(this) | ||
@@ -67,49 +32,6 @@ this.distinct = this.distinct.bind(this) | ||
this.drop = this.drop.bind(this) | ||
util.cast = util.cast.bind(this) | ||
this.executeWhenOpened = this.executeWhenOpened.bind(this) | ||
} | ||
/** | ||
* Execute when connection opened. | ||
* @private | ||
*/ | ||
Collection.prototype.executeWhenOpened = function (fn) { | ||
return this.manager.executeWhenOpened().then(function (db) { | ||
return db.collection(this.name) | ||
}.bind(this)) | ||
this._dispatch = applyMiddlewares(this.middlewares)(manager, this) | ||
} | ||
/** | ||
* Opts utility. | ||
* @private | ||
*/ | ||
Collection.prototype.opts = function (opts) { | ||
opts = util.options(opts || {}) | ||
for (var i in this.manager.options) { | ||
if (!(i in opts) && !(i in this.options)) { | ||
opts[i] = this.manager.options[i] | ||
} | ||
} | ||
for (var j in this.options) { | ||
if (!(j in opts)) { | ||
opts[j] = this.options[j] | ||
} | ||
} | ||
return opts | ||
} | ||
/** | ||
* Calculates aggregate values for the data in a collection. | ||
* | ||
* @param {Array} pipeline - A sequence of data aggregation operations or stages. | ||
* @param {Object|Function} [opts] | ||
* @param {Function} [fn] | ||
* @return {Promise} | ||
*/ | ||
Collection.prototype.aggregate = function (stages, opts, fn) { | ||
@@ -121,25 +43,7 @@ if (typeof opts === 'function') { | ||
// opts | ||
opts = this.opts(opts) | ||
// query | ||
debug('%s aggregate %j', this.name, stages) | ||
return this.executeWhenOpened().then(function (col) { | ||
return col.aggregate(stages, opts) | ||
}).then(function (cursor) { | ||
return cursor.toArray() | ||
}).then(thenFn(fn)).catch(catchFn(fn)) | ||
return this._dispatch(function aggregate (args) { | ||
return args.col.aggregate(args.stages, args.options).toArray() | ||
})({options: opts, stages: stages, callback: fn}, 'aggregate') | ||
} | ||
/** | ||
* Perform a bulkWrite operation without a fluent API | ||
* | ||
* http://mongodb.github.io/node-mongodb-native/2.1/api/Collection.html#bulkWrite | ||
* | ||
* @param {Array} operations - Bulk operations to perform. | ||
* @param {Object} [opts] options | ||
* @param {Function} [fn] callback | ||
* @return {Promise} | ||
*/ | ||
Collection.prototype.bulkWrite = function (operations, opts, fn) { | ||
@@ -151,28 +55,8 @@ if (typeof opts === 'function') { | ||
opts = this.opts(opts) | ||
// cast | ||
if (opts.castIds !== false) { | ||
operations = util.cast(operations) | ||
} | ||
// query | ||
debug('%s bulkWrite %j', this.name, operations) | ||
return this.executeWhenOpened().then(function (col) { | ||
return col.bulkWrite(operations, opts) | ||
}).then(thenFn(fn)).catch(catchFn(fn)) | ||
return this._dispatch(function bulkWrite (args) { | ||
return args.col.bulkWrite(args.operations, args.options) | ||
})({options: opts, operations: operations, callback: fn}, 'bulkWrite') | ||
} | ||
/** | ||
* Returns the count of documents that would match a find() query. The db.collection.count() method does not perform the find() operation but instead counts and returns the number of results that match a query. | ||
* | ||
* @param {Object} query - The query selection criteria. | ||
* @param {Object} [opts] - Extra options for modifying the count. | ||
* @param {Function} [fn] - completion callback. | ||
* @return {Promise} | ||
*/ | ||
Collection.prototype.count = function (query, opts, fn) { | ||
query = util.query(query) | ||
if (typeof opts === 'function') { | ||
@@ -183,27 +67,18 @@ fn = opts | ||
// opts | ||
opts = this.opts(opts) | ||
return this._dispatch(function count (args) { | ||
return args.col.count(args.query, args.options) | ||
})({options: opts, query: query, callback: fn}, 'count') | ||
} | ||
// cast | ||
if (opts.castIds !== false) { | ||
query = util.cast(query) | ||
Collection.prototype.createIndex = function (fields, opts, fn) { | ||
if (typeof opts === 'function') { | ||
fn = opts | ||
opts = {} | ||
} | ||
// query | ||
debug('%s count %j', this.name, query) | ||
return this.executeWhenOpened().then(function (col) { | ||
return col.count(query, opts) | ||
}).then(thenFn(fn)).catch(catchFn(fn)) | ||
return this._dispatch(function createIndex (args) { | ||
return args.col.createIndex(args.fields, args.options) | ||
})({options: opts, fields: fields, callback: fn}, 'createIndex') | ||
} | ||
/** | ||
* Finds the distinct values for a specified field across a single collection and returns the results in an array. | ||
* | ||
* @param {String} field - The field for which to return distinct values. | ||
* @param {Object} [query] - A query that specifies the documents from which to retrieve the distinct values. | ||
* @param {Object} [opts] - options | ||
* @param {Function} [fn] completion callback | ||
* @return {Promise} | ||
*/ | ||
Collection.prototype.distinct = function (field, query, opts, fn) { | ||
@@ -220,50 +95,19 @@ if (typeof opts === 'function') { | ||
query = util.query(query) | ||
// opts | ||
opts = this.opts(opts) | ||
// cast | ||
if (opts.castIds !== false) { | ||
query = util.cast(query) | ||
} | ||
// query | ||
debug('%s distinct %s (%j)', this.name, field, query) | ||
return this.executeWhenOpened().then(function (col) { | ||
return col.distinct(field, query, opts) | ||
}).then(thenFn(fn)).catch(catchFn(fn)) | ||
return this._dispatch(function distinct (args) { | ||
return args.col.distinct(args.field, args.query, args.options) | ||
})({options: opts, query: query, field: field, callback: fn}, 'distinct') | ||
} | ||
/** | ||
* Removes a collection from the database. The method also removes any indexes associated with the dropped collection. | ||
* | ||
* @param {Function} [fn] callback | ||
* @return {Promise} | ||
*/ | ||
Collection.prototype.drop = function (fn) { | ||
debug('%s drop', this.name) | ||
return this.executeWhenOpened().then(function (col) { | ||
return col.drop() | ||
}).catch(function (err) { | ||
if (err && err.message === 'ns not found') { | ||
return 'ns not found' | ||
} else { | ||
throw err | ||
} | ||
}).then(thenFn(fn)).catch(catchFn(fn)) | ||
return this._dispatch(function drop (args) { | ||
return args.col.drop().catch(function (err) { | ||
if (err && err.message === 'ns not found') { | ||
return 'ns not found' | ||
} else { | ||
throw err | ||
} | ||
}) | ||
})({callback: fn}, 'drop') | ||
} | ||
/** | ||
* Drops or removes the specified index or indexes from a collection. | ||
* | ||
* https://docs.mongodb.com/manual/reference/method/db.collection.dropIndex/ | ||
* | ||
* @param {Object|String|Array} fields | ||
* @param {Object} [opts] | ||
* @param {Function} [fn] callback | ||
* @return {Promise} | ||
*/ | ||
Collection.prototype.dropIndex = function (fields, opts, fn) { | ||
@@ -275,71 +119,13 @@ if (typeof opts === 'function') { | ||
fields = util.fields(fields) | ||
opts = this.opts(opts) | ||
// query | ||
debug('%s dropIndex %j (%j)', this.name, fields, opts) | ||
return this.executeWhenOpened().then(function (col) { | ||
return col.dropIndex(fields, opts) | ||
}).then(thenFn(fn)).catch(catchFn(fn)) | ||
return this._dispatch(function dropIndex (args) { | ||
return args.col.dropIndex(args.fields, args.options) | ||
})({options: opts, fields: fields, callback: fn}, 'dropIndex') | ||
} | ||
/** | ||
* Drops all indexes other than the required index on the _id field. | ||
* | ||
* https://docs.mongodb.com/manual/reference/method/db.collection.dropIndexes/ | ||
* | ||
* @param {Function} [fn] callback | ||
* | ||
* @example | ||
* | ||
* users.dropIndexes() | ||
* @return {Promise} | ||
*/ | ||
Collection.prototype.dropIndexes = function (fn) { | ||
// query | ||
debug('%s dropIndexes', this.name) | ||
return this.executeWhenOpened().then(function (col) { | ||
return col.dropIndexes() | ||
}).then(thenFn(fn)).catch(catchFn(fn)) | ||
return this._dispatch(function dropIndexes (args) { | ||
return args.col.dropIndexes() | ||
})({callback: fn}, 'dropIndexes') | ||
} | ||
/** | ||
* Creates indexes on collections. | ||
* | ||
* https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/ | ||
* | ||
* @param {Object|String|Array} fields | ||
* @param {Object} [opts] options | ||
* @param {Function} [fn] callback | ||
* @return {Promise} | ||
*/ | ||
Collection.prototype.createIndex = function (fields, opts, fn) { | ||
if (typeof opts === 'function') { | ||
fn = opts | ||
opts = {} | ||
} | ||
fields = util.fields(fields) | ||
// query | ||
debug('%s createIndex %j (%j)', this.name, fields, opts) | ||
return this.executeWhenOpened().then(function (col) { | ||
return col.createIndex(fields, opts) | ||
}).then(thenFn(fn)).catch(catchFn(fn)) | ||
} | ||
/** | ||
* @deprecated | ||
* Creates indexes on collections. | ||
* | ||
* https://docs.mongodb.com/manual/reference/method/db.collection.ensureIndex/ | ||
* | ||
* @param {Object|String|Array} fields | ||
* @param {Object} [opts] options | ||
* @param {Function} [fn] callback | ||
* @return {Promise} | ||
*/ | ||
Collection.prototype.ensureIndex = function (fields, opts, fn) { | ||
@@ -351,25 +137,10 @@ if (typeof opts === 'function') { | ||
fields = util.fields(fields) | ||
console.warn('DEPRECATED (collection.ensureIndex): use collection.createIndex instead (see https://Automattic.github.io/monk/docs/collection/createIndex.html)') | ||
// query | ||
debug('%s ensureIndex %j (%j)', this.name, fields, opts) | ||
return this.executeWhenOpened().then(function (col) { | ||
return col.ensureIndex(fields, opts) | ||
}).then(thenFn(fn)).catch(catchFn(fn)) | ||
return this._dispatch(function ensureIndex (args) { | ||
return args.col.ensureIndex(args.fields, args.options) | ||
})({options: opts, fields: fields, callback: fn}, 'ensureIndex') | ||
} | ||
/** | ||
* Selects documents in a collection and return them. | ||
* | ||
* @param {String|Object|ObjectId} query | ||
* @param {Object|String|Array} [opts] options or fields | ||
* @param {Function} [fn] completion callback | ||
* @return {Promise} | ||
*/ | ||
Collection.prototype.find = function (query, opts, fn) { | ||
query = util.query(query) | ||
if (typeof opts === 'function') { | ||
@@ -380,29 +151,18 @@ fn = opts | ||
// opts | ||
opts = this.opts(opts) | ||
// cast | ||
if (opts.castIds !== false) { | ||
query = util.cast(query) | ||
if ((opts || {}).rawCursor) { | ||
delete opts.rawCursor | ||
return this._dispatch(function find (args) { | ||
return args.col.find(args.query, args.options) | ||
})({options: opts, query: query, callback: fn}, 'find') | ||
} | ||
// query | ||
debug('%s find %j', this.name, query) | ||
var promise = this._dispatch(function find (args) { | ||
var cursor = args.col.find(args.query, args.options) | ||
if (opts.rawCursor) { | ||
delete opts.rawCursor | ||
return this.executeWhenOpened().then(function (col) { | ||
return col.find(query, opts) | ||
}).then(thenFn(fn)).catch(catchFn(fn)) | ||
} | ||
var promise = this.executeWhenOpened().then(function (col) { | ||
return col.find(query, opts) | ||
}).then(function (cursor) { | ||
if (!opts.stream && !promise.eachListener) { | ||
return cursor.toArray().then(thenFn(fn)).catch(catchFn(fn)) | ||
if (!(opts || {}).stream && !promise.eachListener) { | ||
return cursor.toArray() | ||
} | ||
if (typeof opts.stream === 'function') { | ||
promise.eachListener = opts.stream | ||
if (typeof (opts || {}).stream === 'function') { | ||
promise.eachListener = (opts || {}).stream | ||
} | ||
@@ -464,3 +224,3 @@ | ||
}) | ||
}) | ||
})({options: opts, query: query, callback: fn}, 'find') | ||
@@ -475,85 +235,3 @@ promise.each = function (eachListener) { | ||
/** | ||
* @deprecated | ||
* Modifies and returns a single document. By default, the returned document does not include the modifications made on the update. To return the document with the modifications made on the update, use the `new` option. | ||
* | ||
* @param {Object} search query, or { query, update } object | ||
* @param {Object} [update] object | ||
* @param {Object|String|Array} [opts] options or fields | ||
* @param {Function} [fn] callback | ||
* | ||
* @example | ||
* | ||
* users.findAndModify({ name: 'Mathieu' }, { $set: { foo: 'bar' } }, opts) | ||
* users.findAndModify({ query: { name: 'Mathieu' }, update: { $set: { foo: 'bar' } }}, opts) | ||
* @return {Promise} | ||
*/ | ||
Collection.prototype.findAndModify = function (query, update, opts, fn) { | ||
query = query || {} | ||
if (typeof query.query !== 'object' && typeof query.update !== 'object') { | ||
query = { | ||
query: query, | ||
update: update | ||
} | ||
} else { | ||
fn = opts | ||
opts = update | ||
} | ||
query.query = util.query(query.query) | ||
if (typeof opts === 'function') { | ||
fn = opts | ||
opts = {} | ||
} | ||
opts = this.opts(opts) | ||
console.warn('DEPRECATED (collection.findAndModify): use collection.findOneAndUpdate instead (see https://Automattic.github.io/monk/docs/collection/findOneAndUpdate.html)') | ||
// `new` defaults to `true` for upserts | ||
if (opts.new == null && opts.upsert) { | ||
opts.new = true | ||
} | ||
// cast | ||
if (opts.castIds !== false) { | ||
query.query = util.cast(query.query) | ||
query.update = util.cast(query.update) | ||
} | ||
// query | ||
debug('%s findAndModify %j with %j', this.name, query.query, query.update) | ||
return this.executeWhenOpened().then(function (col) { | ||
return col.findAndModify( | ||
query.query, | ||
[], | ||
query.update, | ||
opts | ||
) | ||
}).then(function (doc) { | ||
return doc && doc.value || doc | ||
}).then(thenFn(fn)).catch(catchFn(fn)) | ||
} | ||
/** | ||
* Returns one document that satisfies the specified query criteria. If multiple documents satisfy the query, this method returns the first document according to the natural order which reflects the order of documents on the disk. In capped collections, natural order is the same as insertion order. If no document satisfies the query, the method returns null. | ||
* | ||
* https://docs.mongodb.com/manual/reference/method/db.collection.findOne/ | ||
* | ||
* @param {String|ObjectId|Object} query | ||
* @param {Object} [opts] - options | ||
* @param {Function} [fn] - completion callback | ||
* | ||
* @example | ||
* | ||
* users.findOne({name: 'foo'}).then((doc) => {}) | ||
* @return {Promise} | ||
*/ | ||
Collection.prototype.findOne = function (query, opts, fn) { | ||
query = util.query(query) | ||
if (typeof opts === 'function') { | ||
@@ -564,50 +242,11 @@ fn = opts | ||
// opts | ||
opts = this.opts(opts) | ||
// cast | ||
if (opts.castIds !== false) { | ||
query = util.cast(query) | ||
} | ||
// query | ||
debug('%s findOne %j', this.name, query) | ||
return this.executeWhenOpened().then(function (col) { | ||
return col.find(query, opts).limit(1).toArray() | ||
}).then(function (docs) { | ||
return docs && docs[0] || null | ||
}).then(thenFn(fn)).catch(catchFn(fn)) | ||
return this._dispatch(function findOne (args) { | ||
return args.col.find(args.query, args.options).limit(1).toArray() | ||
.then(function (docs) { | ||
return (docs && docs[0]) || null | ||
}) | ||
})({options: opts, query: query, callback: fn}, 'findOne') | ||
} | ||
/** | ||
* @deprecated | ||
* findOne by ID helper | ||
* | ||
* @see findOne | ||
* | ||
* @param {String} hex id | ||
* @param {Object|String|Array} [opts] options or fields | ||
* @param {Function} [fn] completion callback | ||
* @return {Promise} | ||
*/ | ||
Collection.prototype.findById = function (id, opts, fn) { | ||
console.warn('DEPRECATED (collection.findById): use collection.findOne instead (see https://Automattic.github.io/monk/docs/collection/findOne.html)') | ||
return this.findOne({ _id: id }, opts, fn) | ||
} | ||
/** | ||
* Find a document and delete it in one atomic operation, requires a write lock for the duration of the operation. | ||
* | ||
* http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#findOneAndDelete | ||
* | ||
* @param {String|Object|ObjectId} query | ||
* @param {Object|String|Array} [opts] options or fields | ||
* @param {Function} [fn] callback | ||
* @return {Promise} | ||
*/ | ||
Collection.prototype.findOneAndDelete = function (query, opts, fn) { | ||
query = util.query(query) | ||
if (typeof opts === 'function') { | ||
@@ -617,39 +256,11 @@ fn = opts | ||
} | ||
opts = this.opts(opts) | ||
// cast | ||
if (opts.castIds !== false) { | ||
query = util.cast(query) | ||
} | ||
// query | ||
debug('%s findOneAndDelete %j with %j', this.name, query) | ||
return this.executeWhenOpened().then(function (col) { | ||
return col.findOneAndDelete(query, opts) | ||
}).then(function (doc) { | ||
return doc && doc.value || doc | ||
}).then(thenFn(fn)).catch(catchFn(fn)) | ||
return this._dispatch(function findOneAndDelete (args) { | ||
return args.col.findOneAndDelete(args.query, args.options) | ||
.then(function (doc) { | ||
return (doc && doc.value) || doc | ||
}) | ||
})({options: opts, query: query, callback: fn}, 'findOneAndDelete') | ||
} | ||
/** | ||
* Find a document and update it in one atomic operation, requires a write lock for the duration of the operation. | ||
* | ||
* http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#findOneAndUpdate | ||
* | ||
* @param {String|Object|ObjectId} query | ||
* @param {Object} update | ||
* @param {Object|String|Array} [opts] options or fields | ||
* @param {Function} [fn] callback | ||
* | ||
* @example | ||
* | ||
* users.findOneAndUpdate({ name: 'Mathieu' }, opts) | ||
* users.findOneAndUpdate({ query: { name: 'Mathieu' }, opts) | ||
* @return {Promise} | ||
*/ | ||
Collection.prototype.findOneAndUpdate = function (query, update, opts, fn) { | ||
query = util.query(query) | ||
if (typeof opts === 'function') { | ||
@@ -659,44 +270,13 @@ fn = opts | ||
} | ||
opts = this.opts(opts) | ||
if (typeof opts.returnOriginal === 'undefined') { | ||
opts.returnOriginal = false | ||
} | ||
// cast | ||
if (opts.castIds !== false) { | ||
query = util.cast(query) | ||
} | ||
// query | ||
debug('%s findOneAndUpdate %j with %j', this.name, query, update) | ||
return this.executeWhenOpened().then(function (col) { | ||
return col.findOneAndUpdate(query, update, opts) | ||
}).then(function (doc) { | ||
return doc && doc.value || doc | ||
}).then(thenFn(fn)).catch(catchFn(fn)) | ||
return this._dispatch(function findOneAndUpdate (args) { | ||
if (typeof (args.options || {}).returnOriginal === 'undefined') { | ||
args.options.returnOriginal = false | ||
} | ||
return args.col.findOneAndUpdate(args.query, args.update, args.options) | ||
.then(function (doc) { | ||
return (doc && doc.value) || doc | ||
}) | ||
})({options: opts, query: query, update: update, callback: fn}, 'findOneAndUpdate') | ||
} | ||
/** | ||
* Run a group command across a collection | ||
* | ||
* http://mongodb.github.io/node-mongodb-native/2.1/api/Collection.html#group | ||
* | ||
* @param {object | array | function} keys - An object, array or function expressing the keys to group by. | ||
* @param {Object} condition - An optional condition that must be true for a row to be considered. | ||
* @param {Object} initial - Initial value of the aggregation counter object. | ||
* @param {Function} reduce - The reduce function aggregates (reduces) the objects iterated. | ||
* @param {Function} [finalize] An optional function to be run on each item in the result set just before the item is returned. | ||
* @param {boolean} [command] Specify if you wish to run using the internal group command or using eval, default is true. | ||
* @param {Object} [opts] options | ||
* @param {Function} [fn] callback | ||
* | ||
* @example | ||
* | ||
* users.findOneAndUpdate({ name: 'Mathieu' }, opts) | ||
* users.findOneAndUpdate({ query: { name: 'Mathieu' }, opts) | ||
* @return {Promise} | ||
*/ | ||
Collection.prototype.group = function (keys, condition, initial, reduce, finalize, command, opts, fn) { | ||
@@ -707,44 +287,13 @@ if (typeof opts === 'function') { | ||
} | ||
opts = this.opts(opts) | ||
// query | ||
debug('%s group %j with %j', this.name, keys, condition) | ||
return this.executeWhenOpened().then(function (col) { | ||
return col.group(keys, condition, initial, reduce, finalize, command, opts) | ||
}).then(thenFn(fn)).catch(catchFn(fn)) | ||
return this._dispatch(function group (args) { | ||
return args.col.group(args.keys, args.condition, args.initial, args.reduce, args.finalize, args.command, args.options) | ||
})({options: opts, keys: keys, condition: condition, initial: initial, reduce: reduce, finalize: finalize, command: command, callback: fn}, 'group') | ||
} | ||
/** | ||
* Returns an array that holds a list of documents that identify and describe the existing indexes on the collection. | ||
* | ||
* https://docs.mongodb.com/manual/reference/method/db.collection.getIndexes/ | ||
* | ||
* @param {Function} [fn] callback | ||
* @return {Promise} | ||
*/ | ||
Collection.prototype.indexes = function (fn) { | ||
debug('%s indexInformation', this.name) | ||
return this.executeWhenOpened().then(function (col) { | ||
return col.indexInformation() | ||
}).then(thenFn(fn)).catch(catchFn(fn)) | ||
return this._dispatch(function indexes (args) { | ||
return args.col.indexInformation() | ||
})({callback: fn}, 'indexes') | ||
} | ||
/** | ||
* Inserts a document or documents into a collection. | ||
* | ||
* https://docs.mongodb.com/manual/reference/method/db.collection.insert/ | ||
* | ||
* @param {Object|Array} data | ||
* @param {Object} [opts] options | ||
* @param {Function} [fn] callback | ||
* | ||
* @example | ||
* | ||
* users.insert({ woot: 'foo' }) | ||
* users.insert([{ woot: 'bar' }, { woot: 'baz' }]) | ||
* @return {Promise} | ||
*/ | ||
Collection.prototype.insert = function (data, opts, fn) { | ||
@@ -756,47 +305,19 @@ if (typeof opts === 'function') { | ||
opts = this.opts(opts) | ||
return this._dispatch(function insert (args) { | ||
var arrayInsert = Array.isArray(args.data) | ||
var arrayInsert = Array.isArray(data) | ||
if (arrayInsert && data.length === 0) { | ||
debug('%s inserting empty array in %j', this.name) | ||
return Promise.resolve([]) | ||
} | ||
// cast | ||
if (opts.castIds !== false) { | ||
data = util.cast(data) | ||
} | ||
// query | ||
debug('%s insert %j', this.name, data) | ||
return this.executeWhenOpened().then(function (col) { | ||
return col.insert(data, opts) | ||
}).then(function (docs) { | ||
var res = (docs || {}).ops | ||
if (res && !arrayInsert) { | ||
res = docs.ops[0] | ||
if (arrayInsert && args.data.length === 0) { | ||
return Promise.resolve([]) | ||
} | ||
return res | ||
}).then(thenFn(fn)).catch(catchFn(fn)) | ||
return args.col.insert(args.data, args.options).then(function (docs) { | ||
var res = (docs || {}).ops | ||
if (res && !arrayInsert) { | ||
res = docs.ops[0] | ||
} | ||
return res | ||
}) | ||
})({data: data, options: opts, callback: fn}, 'insert') | ||
} | ||
/** | ||
* Removes documents from a collection. | ||
* | ||
* https://docs.mongodb.com/manual/reference/method/db.collection.remove/ | ||
* | ||
* @param {Object|ObjectId|String} search query | ||
* @param {Object} [opts] options | ||
* @param {Function} [fn] callback | ||
* | ||
* @example | ||
* | ||
* users.remove({ name: 'Mathieu' }) | ||
* @return {Promise} | ||
*/ | ||
Collection.prototype.remove = function (query, opts, fn) { | ||
query = util.query(query) | ||
if (typeof opts === 'function') { | ||
@@ -806,56 +327,8 @@ fn = opts | ||
} | ||
opts = this.opts(opts) | ||
// cast | ||
if (opts.castIds !== false) { | ||
query = util.cast(query) | ||
} | ||
// query | ||
debug('%s remove %j with %j', this.name, query, opts) | ||
return this.executeWhenOpened().then(function (col) { | ||
return col.remove(query, opts) | ||
}).then(thenFn(fn)).catch(catchFn(fn)) | ||
return this._dispatch(function remove (args) { | ||
return args.col.remove(args.query, args.options) | ||
})({query: query, options: opts, callback: fn}, 'remove') | ||
} | ||
/** | ||
* @deprecated | ||
* remove by ID helper | ||
* @see remove | ||
* | ||
* @param {String} hex id | ||
* @param {Object} [opts] options | ||
* @param {Function} [fn] callback | ||
* | ||
* @example | ||
* | ||
* users.removeById(id) | ||
* @return {Promise} | ||
*/ | ||
Collection.prototype.removeById = function (id, opts, fn) { | ||
console.warn('DEPRECATED (collection.removeById): use collection.remove instead (see https://Automattic.github.io/monk/docs/collection/remove.html)') | ||
return this.remove({ _id: id }, opts, fn) | ||
} | ||
/** | ||
* Modifies an existing document or documents in a collection. The method can modify specific fields of an existing document or documents or replace an existing document entirely, depending on the update parameter. By default, the update() method updates a single document. Set the `multi` option to update all documents that match the query criteria. | ||
* | ||
* https://docs.mongodb.com/manual/reference/method/db.collection.update/ | ||
* | ||
* @param {Object} query | ||
* @param {Object} update obj | ||
* @param {Object|String|Array} [opts], options or fields | ||
* @param {Function} [fn] callback | ||
* | ||
* @example | ||
* | ||
* users.update({ name: 'Mathieu' }, { $set: { foo: 'bar' } }) | ||
* @return {Promise} | ||
*/ | ||
Collection.prototype.update = function (query, update, opts, fn) { | ||
query = util.query(query) | ||
if (typeof opts === 'function') { | ||
@@ -866,47 +339,7 @@ fn = opts | ||
opts = this.opts(opts) | ||
// cast | ||
if (opts.castIds !== false) { | ||
query = util.cast(query) | ||
update = util.cast(update) | ||
} | ||
// query | ||
debug('%s update %j with %j', this.name, query, update) | ||
return this.executeWhenOpened().then(function (col) { | ||
return col.update(query, update, opts) | ||
}).then(function (doc) { | ||
return doc && doc.result || doc | ||
}).then(thenFn(fn)).catch(catchFn(fn)) | ||
return this._dispatch(function update (args) { | ||
return args.col.update(args.query, args.update, args.options).then(function (doc) { | ||
return (doc && doc.result) || doc | ||
}) | ||
})({update: update, query: query, options: opts, callback: fn}, 'remove') | ||
} | ||
/** | ||
* @deprecated | ||
* update by id helper | ||
* @see update | ||
* | ||
* @param {String|Object} id - object id | ||
* @param {Object} update - update obj | ||
* @param {Object|String|Array} [opts] options or fields | ||
* @param {Function} [fn] callback | ||
* | ||
* @example | ||
* | ||
* users.updateById(id, { $set: { foo: 'bar' } }) | ||
* @return {Promise} | ||
*/ | ||
Collection.prototype.updateById = function (id, update, opts, fn) { | ||
console.warn('DEPRECATED (collection.updateById): use collection.update instead (see https://Automattic.github.io/monk/docs/collection/update.html)') | ||
return this.update({ _id: id }, update, opts, fn) | ||
} | ||
/** | ||
* @deprecated | ||
*/ | ||
Collection.prototype.id = function (str) { | ||
console.warn('DEPRECATED (collection.id): use monk.id instead (see https://Automattic.github.io/monk/docs/id.html)') | ||
return require('./helpers').id(str) | ||
} |
@@ -15,1 +15,35 @@ var ObjectId = require('mongodb').ObjectID | ||
} | ||
/** | ||
* Applies ObjectId casting to _id fields. | ||
* | ||
* @param {Object} optional, query | ||
* @return {Object} query | ||
* @private | ||
*/ | ||
exports.cast = function cast (obj) { | ||
if (Array.isArray(obj)) { | ||
return obj.map(cast) | ||
} | ||
if (obj && typeof obj === 'object') { | ||
Object.keys(obj).forEach(function (k) { | ||
if (k === '_id' && obj._id) { | ||
if (obj._id.$in) { | ||
obj._id.$in = obj._id.$in.map(exports.id) | ||
} else if (obj._id.$nin) { | ||
obj._id.$nin = obj._id.$nin.map(exports.id) | ||
} else if (obj._id.$ne) { | ||
obj._id.$ne = exports.id(obj._id.$ne) | ||
} else { | ||
obj._id = exports.id(obj._id) | ||
} | ||
} else { | ||
obj[k] = cast(obj[k]) | ||
} | ||
}) | ||
} | ||
return obj | ||
} |
@@ -7,2 +7,3 @@ /* | ||
var Debug = require('debug') | ||
var objectAssign = require('object-assign') | ||
var monkDebug = Debug('monk:manager') | ||
@@ -12,19 +13,5 @@ var Collection = require('./collection') | ||
var MongoClient = mongo.MongoClient | ||
var Logger = mongo.Logger | ||
var EventEmitter = require('events').EventEmitter | ||
var inherits = require('util').inherits | ||
/* | ||
* Logger | ||
*/ | ||
Logger.setCurrentLogger(function (msg, context) { | ||
if (context.type === 'error') { | ||
return console.error(msg) | ||
} | ||
var logger = Debug('mongo:' + context.className) | ||
logger.log = console.log.bind(console) | ||
logger(context.type.toUpperCase() + ': ' + context.message) | ||
}) | ||
Logger.setLevel('debug') // set the level to `debug` so we have everything going through debug | ||
var STATE = { | ||
@@ -36,2 +23,18 @@ CLOSED: 'closed', | ||
var FIELDS_TO_CAST = ['operations', 'query', 'data', 'update'] | ||
var DEFAULT_OPTIONS = { | ||
safe: true, | ||
castIds: true, | ||
wrapNon$UpdateField: true, | ||
middlewares: [ | ||
require('monk-plugin-query'), | ||
require('monk-plugin-options'), | ||
require('monk-plugin-cast-ids')(FIELDS_TO_CAST), | ||
require('monk-plugin-fields'), | ||
require('monk-plugin-handle-callback'), | ||
require('monk-plugin-wait-for-connection') | ||
] | ||
} | ||
/* | ||
@@ -69,2 +72,5 @@ * Module exports. | ||
this._collectionOptions = objectAssign({}, DEFAULT_OPTIONS, opts.collectionOptions || {}) | ||
delete opts.collectionOptions | ||
if (Array.isArray(uri)) { | ||
@@ -74,3 +80,3 @@ if (!opts.database) { | ||
if (!opts.database) { | ||
opts.database = uri[i].replace(/([^\/])+\/?/, '') | ||
opts.database = uri[i].replace(/([^\/])+\/?/, '') // eslint-disable-line | ||
} | ||
@@ -113,3 +119,2 @@ uri[i] = uri[i].replace(/\/.*/, '') | ||
this.collections = {} | ||
this.options = { safe: true } | ||
@@ -121,2 +126,4 @@ this.open = this.open.bind(this) | ||
this.oid = this.id | ||
this.setDefaultCollectionOptions = this.setDefaultCollectionOptions.bind(this) | ||
this.addMiddleware = this.addMiddleware.bind(this) | ||
} | ||
@@ -253,3 +260,4 @@ | ||
if ((options || {}).cache === false || !this.collections[name]) { | ||
this.collections[name] = new Collection(this, name, options) | ||
delete (options || {}).cache | ||
this.collections[name] = new Collection(this, name, objectAssign({}, this._collectionOptions || {}, options || {})) | ||
} | ||
@@ -276,16 +284,25 @@ | ||
if ((options || {}).cache === false || !this.collections[name]) { | ||
this.collections[name] = new Collection(this, name, options) | ||
} | ||
return this.get(name, options) | ||
} | ||
return this.collections[name] | ||
Manager.prototype.setDefaultCollectionOptions = function (options) { | ||
this._collectionOptions = options | ||
} | ||
/** | ||
* @deprecated | ||
*/ | ||
Manager.prototype.addMiddleware = function (middleware) { | ||
if (!this._collectionOptions) { | ||
this._collectionOptions = {} | ||
} | ||
if (!this._collectionOptions.middlewares) { | ||
this._collectionOptions.middlewares = [] | ||
} | ||
this._collectionOptions.middlewares.push(middleware) | ||
} | ||
Manager.prototype.id = function (str) { | ||
console.warn('DEPRECATED (manager.id): use monk.id instead (see https://Automattic.github.io/monk/docs/id.html)') | ||
return require('./helpers').id(str) | ||
} | ||
Manager.prototype.cast = function (obj) { | ||
return require('./helpers').cast(obj) | ||
} |
@@ -15,8 +15,2 @@ | ||
/* | ||
* Expose util | ||
*/ | ||
exports.util = require('./util') | ||
/* | ||
* Expose helpers at the top level | ||
@@ -23,0 +17,0 @@ */ |
The MIT License (MIT) | ||
Copyright (c) 2016 Automattic | ||
Copyright (c) 2012 Guillermo Rauch <guillermo@learnboost.com> | ||
@@ -5,0 +5,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy |
{ | ||
"name": "monk", | ||
"description": "The wise MongoDB API", | ||
"version": "4.1.0", | ||
"version": "5.0.0", | ||
"main": "lib/monk.js", | ||
"tags": [ | ||
"keywords": [ | ||
"monk", | ||
"mongodb", | ||
@@ -20,4 +21,10 @@ "mongo", | ||
"debug": "*", | ||
"gitbook-plugin-github": "2.0.0", | ||
"mongodb": "^2.1.18" | ||
"mongodb": "^2.1.18", | ||
"monk-middleware-cast-ids": "^0.2.0", | ||
"monk-middleware-fields": "^0.2.0", | ||
"monk-middleware-handle-callback": "^0.2.0", | ||
"monk-middleware-options": "^0.2.0", | ||
"monk-middleware-query": "^0.2.0", | ||
"monk-middleware-wait-for-connection": "^0.2.0", | ||
"object-assign": "^4.1.1" | ||
}, | ||
@@ -36,4 +43,4 @@ "devDependencies": { | ||
"gitbook-plugin-anker-enable": "^0.0.4", | ||
"gitbook-plugin-edit-link": "^2.0.2", | ||
"gitbook-plugin-github": "^3.0.0", | ||
"gitbook-plugin-edit-link": "2.0.2", | ||
"gitbook-plugin-github": "^2.0.0", | ||
"gitbook-plugin-prism": "^2.2.0", | ||
@@ -40,0 +47,0 @@ "nyc": "^10.3.2" |
@@ -1,3 +0,13 @@ | ||
# monk | ||
<h1 align="center">Monk</h1> | ||
<div align="center"> | ||
<img src="https://avatars2.githubusercontent.com/u/28830676?v=3&s=200" /> | ||
</div> | ||
<br /> | ||
<div align="center"> | ||
<strong>A tiny layer that provides simple yet substantial usability | ||
improvements for MongoDB usage within Node.JS.</strong> | ||
</div> | ||
<br /> | ||
[![build status](https://secure.travis-ci.org/Automattic/monk.svg?branch=master)](https://secure.travis-ci.org/Automattic/monk) | ||
@@ -7,5 +17,2 @@ [![codecov](https://codecov.io/gh/Automattic/monk/branch/master/graph/badge.svg)](https://codecov.io/gh/Automattic/monk) | ||
Monk is a tiny layer that provides simple yet substantial usability | ||
improvements for MongoDB usage within Node.JS. | ||
*note*: monk 2.x drop the support for node < 0.12. If you are still using an earlier version, stick to monk 1.x | ||
@@ -32,8 +39,6 @@ | ||
- Command buffering. You can start querying right away. | ||
- Promises built-in for all queries. Easy interoperability with modules. | ||
- Well-designed API signatures | ||
- Easy connections / configuration | ||
- Well-designed signatures | ||
- Improvements to the MongoDB APIs (eg: `findAndModify` supports the | ||
`update` signature style) | ||
- Command buffering. You can start querying right away | ||
- Promises built-in for all queries. Easy interoperability with modules | ||
- Auto-casting of `_id` in queries | ||
@@ -43,29 +48,18 @@ - Allows to set global options or collection-level options for queries. (eg: | ||
## How to use | ||
## Middlewares | ||
[Documentation](https://Automattic.github.io/monk) | ||
Most of the Monk's features are implemented as [middleware](https://automattic.github.io/monk/docs/middlewares.html). | ||
## License | ||
There are a bunch of third-parties middlewares that add even more functionalities to Monk: | ||
- [monk-middleware-wrap-non-dollar-update](https://github.com/monk-middlewares/monk-middleware-wrap-non-dollar-update) | ||
- [monk-middleware-debug](https://github.com/monk-middlewares/monk-middleware-debug) | ||
(The MIT License) | ||
*Created an nice middleware? Send a PR to add to the list!* | ||
Copyright (c) 2012 Guillermo Rauch <guillermo@learnboost.com> | ||
## How to use | ||
Permission is hereby granted, free of charge, to any person obtaining | ||
a copy of this software and associated documentation files (the | ||
'Software'), to deal in the Software without restriction, including | ||
without limitation the rights to use, copy, modify, merge, publish, | ||
distribute, sublicense, and/or sell copies of the Software, and to | ||
permit persons to whom the Software is furnished to do so, subject to | ||
the following conditions: | ||
[Documentation](https://Automattic.github.io/monk) | ||
The above copyright notice and this permission notice shall be | ||
included in all copies or substantial portions of the Software. | ||
## License | ||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
MIT |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
10
30689
9
641
63
1
+ Addedmonk-middleware-query@^0.2.0
+ Addedobject-assign@^4.1.1
+ Addedmonk-middleware-cast-ids@0.2.1(transitive)
+ Addedmonk-middleware-fields@0.2.0(transitive)
+ Addedmonk-middleware-handle-callback@0.2.2(transitive)
+ Addedmonk-middleware-options@0.2.1(transitive)
+ Addedmonk-middleware-query@0.2.0(transitive)
+ Addedmonk-middleware-wait-for-connection@0.2.0(transitive)
+ Addedobject-assign@4.1.1(transitive)
- Removedgitbook-plugin-github@2.0.0
- Removedgitbook-plugin-github@2.0.0(transitive)