From bd420c519fc774d19e2102fa598e8015d99f48b0 Mon Sep 17 00:00:00 2001 From: Jason Dobry Date: Tue, 23 Aug 2016 13:16:38 -0700 Subject: [PATCH] 1.0.0-rc.1 --- dist/js-data-mongodb.js | 774 +++++++++++++++++++++--------------- dist/js-data-mongodb.js.map | 2 +- 2 files changed, 462 insertions(+), 314 deletions(-) diff --git a/dist/js-data-mongodb.js b/dist/js-data-mongodb.js index 29212b0..c655654 100644 --- a/dist/js-data-mongodb.js +++ b/dist/js-data-mongodb.js @@ -1,5 +1,7 @@ 'use strict'; +Object.defineProperty(exports, '__esModule', { value: true }); + function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var mongodb = require('mongodb'); @@ -8,47 +10,26 @@ var jsData = require('js-data'); var jsDataAdapter = require('js-data-adapter'); var underscore = _interopDefault(require('mout/string/underscore')); -var babelHelpers = {}; - -babelHelpers.slicedToArray = function () { - function sliceIterator(arr, i) { - var _arr = []; - var _n = true; - var _d = false; - var _e = undefined; - - try { - for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { - _arr.push(_s.value); - - if (i && _arr.length === i) break; - } - } catch (err) { - _d = true; - _e = err; - } finally { - try { - if (!_n && _i["return"]) _i["return"](); - } finally { - if (_d) throw _e; - } - } +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { + return typeof obj; +} : function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; +}; - return _arr; +var defineProperty = function (obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; } - return function (arr, i) { - if (Array.isArray(arr)) { - return arr; - } else if (Symbol.iterator in Object(arr)) { - return sliceIterator(arr, i); - } else { - throw new TypeError("Invalid attempt to destructure non-iterable instance"); - } - }; -}(); - -babelHelpers; + return obj; +}; var DEFAULTS = { /** @@ -59,6 +40,12 @@ var DEFAULTS = { * @default true */ translateId: true, + /** + * Convert fields of record from databse that are ObjectIDs to strings + * @type {Boolean} + * @default false + */ + translateObjectIDs: false, /** * MongoDB URI. @@ -105,172 +92,178 @@ var REMOVE_OPTS_DEFAULTS = {}; * * @class MongoDBAdapter * @extends Adapter - * @param {Object} [opts] Configuration options. + * @param {object} [opts] Configuration options. * @param {boolean} [opts.debug=false] See {@link Adapter#debug}. - * @param {Object} [opts.countOpts] See {@link MongoDBAdapter#countOpts}. - * @param {Object} [opts.findOpts] See {@link MongoDBAdapter#findOpts}. - * @param {Object} [opts.findOneOpts] See {@link MongoDBAdapter#findOneOpts}. - * @param {Object} [opts.insertOpts] See {@link MongoDBAdapter#insertOpts}. - * @param {Object} [opts.insertManyOpts] See {@link MongoDBAdapter#insertManyOpts}. + * @param {object} [opts.countOpts] See {@link MongoDBAdapter#countOpts}. + * @param {object} [opts.findOpts] See {@link MongoDBAdapter#findOpts}. + * @param {object} [opts.findOneOpts] See {@link MongoDBAdapter#findOneOpts}. + * @param {object} [opts.insertOpts] See {@link MongoDBAdapter#insertOpts}. + * @param {object} [opts.insertManyOpts] See {@link MongoDBAdapter#insertManyOpts}. * @param {boolean} [opts.raw=false] See {@link Adapter#raw}. - * @param {Object} [opts.removeOpts] See {@link MongoDBAdapter#removeOpts}. + * @param {object} [opts.removeOpts] See {@link MongoDBAdapter#removeOpts}. * @param {boolean} [opts.translateId=true] See {@link MongoDBAdapter#translateId}. - * @param {Object} [opts.updateOpts] See {@link MongoDBAdapter#updateOpts}. + * @param {object} [opts.updateOpts] See {@link MongoDBAdapter#updateOpts}. * @param {string} [opts.uri="mongodb://localhost:27017"] See {@link MongoDBAdapter#uri}. */ function MongoDBAdapter(opts) { - var self = this; - jsData.utils.classCallCheck(self, MongoDBAdapter); + var _this = this; + + jsData.utils.classCallCheck(this, MongoDBAdapter); opts || (opts = {}); if (jsData.utils.isString(opts)) { opts = { uri: opts }; } jsData.utils.fillIn(opts, DEFAULTS); - jsDataAdapter.Adapter.call(self, opts); + + // Setup non-enumerable properties + Object.defineProperties(this, { + /** + * A Promise that resolves to a reference to the MongoDB client being used by + * this adapter. + * + * @name MongoDBAdapter#client + * @type {Promise} + */ + client: { + writable: true, + value: undefined + }, + + _db: { + writable: true, + value: undefined + } + }); + + jsDataAdapter.Adapter.call(this, opts); /** * Default options to pass to collection#count. * * @name MongoDBAdapter#countOpts - * @type {Object} + * @type {object} * @default {} */ - self.countOpts || (self.countOpts = {}); - jsData.utils.fillIn(self.countOpts, COUNT_OPTS_DEFAULTS); + this.countOpts || (this.countOpts = {}); + jsData.utils.fillIn(this.countOpts, COUNT_OPTS_DEFAULTS); /** * Default options to pass to collection#find. * * @name MongoDBAdapter#findOpts - * @type {Object} + * @type {object} * @default {} */ - self.findOpts || (self.findOpts = {}); - jsData.utils.fillIn(self.findOpts, FIND_OPTS_DEFAULTS); + this.findOpts || (this.findOpts = {}); + jsData.utils.fillIn(this.findOpts, FIND_OPTS_DEFAULTS); /** * Default options to pass to collection#findOne. * * @name MongoDBAdapter#findOneOpts - * @type {Object} + * @type {object} * @default {} */ - self.findOneOpts || (self.findOneOpts = {}); - jsData.utils.fillIn(self.findOneOpts, FIND_ONE_OPTS_DEFAULTS); + this.findOneOpts || (this.findOneOpts = {}); + jsData.utils.fillIn(this.findOneOpts, FIND_ONE_OPTS_DEFAULTS); /** * Default options to pass to collection#insert. * * @name MongoDBAdapter#insertOpts - * @type {Object} + * @type {object} * @default {} */ - self.insertOpts || (self.insertOpts = {}); - jsData.utils.fillIn(self.insertOpts, INSERT_OPTS_DEFAULTS); + this.insertOpts || (this.insertOpts = {}); + jsData.utils.fillIn(this.insertOpts, INSERT_OPTS_DEFAULTS); /** * Default options to pass to collection#insertMany. * * @name MongoDBAdapter#insertManyOpts - * @type {Object} + * @type {object} * @default {} */ - self.insertManyOpts || (self.insertManyOpts = {}); - jsData.utils.fillIn(self.insertManyOpts, INSERT_MANY_OPTS_DEFAULTS); + this.insertManyOpts || (this.insertManyOpts = {}); + jsData.utils.fillIn(this.insertManyOpts, INSERT_MANY_OPTS_DEFAULTS); /** * Default options to pass to collection#update. * * @name MongoDBAdapter#updateOpts - * @type {Object} + * @type {object} * @default {} */ - self.updateOpts || (self.updateOpts = {}); - jsData.utils.fillIn(self.updateOpts, UPDATE_OPTS_DEFAULTS); + this.updateOpts || (this.updateOpts = {}); + jsData.utils.fillIn(this.updateOpts, UPDATE_OPTS_DEFAULTS); /** * Default options to pass to collection#update. * * @name MongoDBAdapter#removeOpts - * @type {Object} + * @type {object} * @default {} */ - self.removeOpts || (self.removeOpts = {}); - jsData.utils.fillIn(self.removeOpts, REMOVE_OPTS_DEFAULTS); + this.removeOpts || (this.removeOpts = {}); + jsData.utils.fillIn(this.removeOpts, REMOVE_OPTS_DEFAULTS); - /** - * A Promise that resolves to a reference to the MongoDB client being used by - * this adapter. - * - * @name MongoDBAdapter#client - * @type {Object} - */ - self.client = new Promise(function (resolve, reject) { + this.client = new jsData.utils.Promise(function (resolve, reject) { mongodb.MongoClient.connect(opts.uri, function (err, db) { - return err ? reject(err) : resolve(db); + if (err) { + return reject(err); + } + _this._db = db; + resolve(db); }); }); } -// Setup prototype inheritance from Adapter -MongoDBAdapter.prototype = Object.create(jsDataAdapter.Adapter.prototype, { - constructor: { - value: MongoDBAdapter, - enumerable: false, - writable: true, - configurable: true - } -}); +jsDataAdapter.Adapter.extend({ + constructor: MongoDBAdapter, -Object.defineProperty(MongoDBAdapter, '__super__', { - configurable: true, - value: jsDataAdapter.Adapter -}); + _translateObjectIDs: function _translateObjectIDs(r, opts) { + opts || (opts = {}); + if (this.getOpt('translateObjectIDs', opts)) { + this._translateFieldObjectIDs(r); + } else if (this.getOpt('translateId', opts)) { + this._translateId(r); + } + return r; + }, -/** - * Alternative to ES6 class syntax for extending `MongoDBAdapter`. - * - * @example Using the ES2015 class syntax. - * class MyMongoDBAdapter extends MongoDBAdapter {...} - * const adapter = new MyMongoDBAdapter() - * - * @example Using {@link MongoDBAdapter.extend}. - * var instanceProps = {...} - * var classProps = {...} - * - * var MyMongoDBAdapter = MongoDBAdapter.extend(instanceProps, classProps) - * var adapter = new MyMongoDBAdapter() - * - * @method MongoDBAdapter.extend - * @static - * @param {Object} [instanceProps] Properties that will be added to the - * prototype of the subclass. - * @param {Object} [classProps] Properties that will be added as static - * properties to the subclass itself. - * @return {Object} Subclass of `MongoDBAdapter`. - */ -MongoDBAdapter.extend = jsData.utils.extend; -jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { /** * Translate ObjectIDs to strings. * * @method MongoDBAdapter#_translateId * @return {*} */ - - _translateId: function _translateId(r, opts) { - opts || (opts = {}); - if (this.getOpt('translateId', opts)) { - if (jsData.utils.isArray(r)) { - r.forEach(function (_r) { - var __id = _r._id ? _r._id.toString() : _r._id; - _r._id = typeof __id === 'string' ? __id : _r._id; - }); - } else if (jsData.utils.isObject(r)) { - var __id = r._id ? r._id.toString() : r._id; - r._id = typeof __id === 'string' ? __id : r._id; + _translateId: function _translateId(r) { + if (jsData.utils.isArray(r)) { + r.forEach(function (_r) { + var __id = _r._id ? _r._id.toString() : _r._id; + _r._id = typeof __id === 'string' ? __id : _r._id; + }); + } else if (jsData.utils.isObject(r)) { + var __id = r._id ? r._id.toString() : r._id; + r._id = typeof __id === 'string' ? __id : r._id; + } + return r; + }, + _translateFieldObjectIDs: function _translateFieldObjectIDs(r) { + var _checkFields = function _checkFields(r) { + for (var field in r) { + if (r[field]._bsontype === 'ObjectID') { + r[field] = typeof r[field].toString() === 'string' ? r[field].toString() : r[field]; + } } + }; + if (jsData.utils.isArray(r)) { + r.forEach(function (_r) { + _checkFields(_r); + }); + } else if (jsData.utils.isObject(r)) { + _checkFields(r); } return r; }, @@ -280,10 +273,10 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { * Retrieve the number of records that match the selection query. * * @method MongoDBAdapter#count - * @param {Object} mapper The mapper. - * @param {Object} query Selection query. - * @param {Object} [opts] Configuration options. - * @param {Object} [opts.countOpts] Options to pass to collection#count. + * @param {object} mapper The mapper. + * @param {object} query Selection query. + * @param {object} [opts] Configuration options. + * @param {object} [opts.countOpts] Options to pass to collection#count. * @param {boolean} [opts.raw=false] Whether to return a more detailed * response object. * @param {string[]} [opts.with=[]] Relations to eager load. @@ -296,24 +289,25 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { * * @method MongoDBAdapter#_count * @private - * @param {Object} mapper The mapper. - * @param {Object} query Selection query. - * @param {Object} [opts] Configuration options. + * @param {object} mapper The mapper. + * @param {object} query Selection query. + * @param {object} [opts] Configuration options. * @return {Promise} */ _count: function _count(mapper, query, opts) { - var self = this; + var _this2 = this; + opts || (opts = {}); - var countOpts = self.getOpt('countOpts', opts); - jsData.utils.fillIn(countOpts, self.getQueryOptions(mapper, query)); - var mongoQuery = self.getQuery(mapper, query); + return this._run(function (client, success, failure) { + var collectionId = _this2._getCollectionId(mapper, opts); + var countOpts = _this2.getOpt('countOpts', opts); + jsData.utils.fillIn(countOpts, _this2.getQueryOptions(mapper, query)); - return self.getClient().then(function (client) { - return new Promise(function (resolve, reject) { - client.collection(mapper.table || underscore(mapper.name)).count(mongoQuery, countOpts, function (err, count) { - return err ? reject(err) : resolve([count, {}]); - }); + var mongoQuery = _this2.getQuery(mapper, query); + + client.collection(collectionId).count(mongoQuery, countOpts, function (err, count) { + return err ? failure(err) : success([count, {}]); }); }); }, @@ -323,10 +317,10 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { * Create a new record. * * @method MongoDBAdapter#create - * @param {Object} mapper The mapper. - * @param {Object} props The record to be created. - * @param {Object} [opts] Configuration options. - * @param {Object} [opts.insertOpts] Options to pass to collection#insert. + * @param {object} mapper The mapper. + * @param {object} props The record to be created. + * @param {object} [opts] Configuration options. + * @param {object} [opts.insertOpts] Options to pass to collection#insert. * @param {boolean} [opts.raw=false] Whether to return a more detailed * @return {Promise} */ @@ -336,31 +330,37 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { * * @method MongoDBAdapter#_create * @private - * @param {Object} mapper The mapper. - * @param {Object} props The record to be created. - * @param {Object} [opts] Configuration options. + * @param {object} mapper The mapper. + * @param {object} props The record to be created. + * @param {object} [opts] Configuration options. * @return {Promise} */ _create: function _create(mapper, props, opts) { - var self = this; + var _this3 = this; + props || (props = {}); opts || (opts = {}); - props = jsData.utils.plainCopy(props); - var insertOpts = self.getOpt('insertOpts', opts); + return this._run(function (client, success, failure) { + var collectionId = _this3._getCollectionId(mapper, opts); + var insertOpts = _this3.getOpt('insertOpts', opts); - return self.getClient().then(function (client) { - return new Promise(function (resolve, reject) { - var collection = client.collection(mapper.table || underscore(mapper.name)); - var method = collection.insertOne ? 'insertOne' : 'insert'; - collection[method](props, insertOpts, function (err, cursor) { - return err ? reject(err) : resolve(cursor); - }); - }); + var collection = client.collection(collectionId); + var handler = function handler(err, cursor) { + return err ? failure(err) : success(cursor); + }; + + props = jsData.utils.plainCopy(props); + + if (collection.insertOne) { + collection.insertOne(props, insertOpts, handler); + } else { + collection.insert(props, insertOpts, handler); + } }).then(function (cursor) { var record = void 0; var r = cursor.ops ? cursor.ops : cursor; - self._translateId(r, opts); + _this3._translateObjectIDs(r, opts); record = jsData.utils.isArray(r) ? r[0] : r; cursor.connection = undefined; return [record, cursor]; @@ -372,10 +372,10 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { * Create multiple records in a single batch. * * @method MongoDBAdapter#createMany - * @param {Object} mapper The mapper. - * @param {Object} props The records to be created. - * @param {Object} [opts] Configuration options. - * @param {Object} [opts.insertManyOpts] Options to pass to + * @param {object} mapper The mapper. + * @param {object} props The records to be created. + * @param {object} [opts] Configuration options. + * @param {object} [opts.insertManyOpts] Options to pass to * collection#insertMany. * @param {boolean} [opts.raw=false] Whether to return a more detailed * response object. @@ -388,30 +388,29 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { * * @method MongoDBAdapter#_createMany * @private - * @param {Object} mapper The mapper. - * @param {Object} props The records to be created. - * @param {Object} [opts] Configuration options. + * @param {object} mapper The mapper. + * @param {object} props The records to be created. + * @param {object} [opts] Configuration options. * @return {Promise} */ _createMany: function _createMany(mapper, props, opts) { - var self = this; + var _this4 = this; + props || (props = {}); opts || (opts = {}); - props = jsData.utils.plainCopy(props); - var insertManyOpts = self.getOpt('insertManyOpts', opts); + return this._run(function (client, success, failure) { + var collectionId = _this4._getCollectionId(mapper, opts); + var insertManyOpts = _this4.getOpt('insertManyOpts', opts); + props = jsData.utils.plainCopy(props); - return self.getClient().then(function (client) { - return new Promise(function (resolve, reject) { - var collection = client.collection(mapper.table || underscore(mapper.name)); - collection.insertMany(props, insertManyOpts, function (err, cursor) { - return err ? reject(err) : resolve(cursor); - }); + client.collection(collectionId).insertMany(props, insertManyOpts, function (err, cursor) { + return err ? failure(err) : success(cursor); }); }).then(function (cursor) { var records = []; var r = cursor.ops ? cursor.ops : cursor; - self._translateId(r, opts); + _this4._translateObjectIDs(r, opts); records = r; cursor.connection = undefined; return [records, cursor]; @@ -423,12 +422,12 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { * Destroy the record with the given primary key. * * @method MongoDBAdapter#destroy - * @param {Object} mapper The mapper. + * @param {object} mapper The mapper. * @param {(string|number)} id Primary key of the record to destroy. - * @param {Object} [opts] Configuration options. + * @param {object} [opts] Configuration options. * @param {boolean} [opts.raw=false] Whether to return a more detailed * response object. - * @param {Object} [opts.removeOpts] Options to pass to collection#remove. + * @param {object} [opts.removeOpts] Options to pass to collection#remove. * @return {Promise} */ @@ -438,25 +437,31 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { * * @method MongoDBAdapter#_destroy * @private - * @param {Object} mapper The mapper. + * @param {object} mapper The mapper. * @param {(string|number)} id Primary key of the record to destroy. - * @param {Object} [opts] Configuration options. + * @param {object} [opts] Configuration options. * @return {Promise} */ _destroy: function _destroy(mapper, id, opts) { - var self = this; + var _this5 = this; + opts || (opts = {}); - var removeOpts = self.getOpt('removeOpts', opts); - - return self.getClient().then(function (client) { - return new Promise(function (resolve, reject) { - var mongoQuery = {}; - mongoQuery[mapper.idAttribute] = self.toObjectID(mapper, id); - var collection = client.collection(mapper.table || underscore(mapper.name)); - collection[collection.deleteOne ? 'deleteOne' : 'remove'](mongoQuery, removeOpts, function (err, cursor) { - return err ? reject(err) : resolve(cursor); - }); - }); + + return this._run(function (client, success, failure) { + var collectionId = _this5._getCollectionId(mapper, opts); + var removeOpts = _this5.getOpt('removeOpts', opts); + + var mongoQuery = defineProperty({}, mapper.idAttribute, _this5.toObjectID(mapper, id)); + var collection = client.collection(collectionId); + var handler = function handler(err, cursor) { + return err ? failure(err) : success(cursor); + }; + + if (collection.deleteOne) { + collection.deleteOne(mongoQuery, removeOpts, handler); + } else { + collection.remove(mongoQuery, removeOpts, handler); + } }).then(function (cursor) { return [undefined, cursor]; }); @@ -467,18 +472,18 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { * Destroy the records that match the selection query. * * @method MongoDBAdapter#destroyAll - * @param {Object} mapper the mapper. - * @param {Object} [query] Selection query. - * @param {Object} [query.where] Filtering criteria. + * @param {object} mapper the mapper. + * @param {object} [query] Selection query. + * @param {object} [query.where] Filtering criteria. * @param {string|Array} [query.orderBy] Sorting criteria. * @param {string|Array} [query.sort] Same as `query.sort`. * @param {number} [query.limit] Limit results. * @param {number} [query.skip] Offset results. * @param {number} [query.offset] Same as `query.skip`. - * @param {Object} [opts] Configuration options. + * @param {object} [opts] Configuration options. * @param {boolean} [opts.raw=false] Whether to return a more detailed * response object. - * @param {Object} [opts.removeOpts] Options to pass to collection#remove. + * @param {object} [opts.removeOpts] Options to pass to collection#remove. * @return {Promise} */ @@ -488,26 +493,33 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { * * @method MongoDBAdapter#_destroyAll * @private - * @param {Object} mapper the mapper. - * @param {Object} [query] Selection query. - * @param {Object} [opts] Configuration options. + * @param {object} mapper the mapper. + * @param {object} [query] Selection query. + * @param {object} [opts] Configuration options. * @return {Promise} */ _destroyAll: function _destroyAll(mapper, query, opts) { - var self = this; + var _this6 = this; + query || (query = {}); opts || (opts = {}); - var removeOpts = self.getOpt('removeOpts', opts); - jsData.utils.fillIn(removeOpts, self.getQueryOptions(mapper, query)); - - return self.getClient().then(function (client) { - var mongoQuery = self.getQuery(mapper, query); - return new Promise(function (resolve, reject) { - var collection = client.collection(mapper.table || underscore(mapper.name)); - collection[collection.deleteMany ? 'deleteMany' : 'remove'](mongoQuery, removeOpts, function (err, cursor) { - return err ? reject(err) : resolve(cursor); - }); - }); + + return this._run(function (client, success, failure) { + var collectionId = _this6._getCollectionId(mapper, opts); + var removeOpts = _this6.getOpt('removeOpts', opts); + jsData.utils.fillIn(removeOpts, _this6.getQueryOptions(mapper, query)); + + var mongoQuery = _this6.getQuery(mapper, query); + var collection = client.collection(collectionId); + var handler = function handler(err, cursor) { + return err ? failure(err) : success(cursor); + }; + + if (collection.deleteMany) { + collection.deleteMany(mongoQuery, removeOpts, handler); + } else { + collection.remove(mongoQuery, removeOpts, handler); + } }).then(function (cursor) { cursor.connection = undefined; return [undefined, cursor]; @@ -519,10 +531,11 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { * Retrieve the record with the given primary key. * * @method MongoDBAdapter#find - * @param {Object} mapper The mapper. + * @param {object} mapper The mapper. * @param {(string|number)} id Primary key of the record to retrieve. - * @param {Object} [opts] Configuration options. - * @param {Object} [opts.findOneOpts] Options to pass to collection#findOne. + * @param {object} [opts] Configuration options. + * @param {string|string[]|object} [opts.fields] Select a subset of fields to be returned. + * @param {object} [opts.findOneOpts] Options to pass to collection#findOne. * @param {boolean} [opts.raw=false] Whether to return a more detailed * response object. * @param {string[]} [opts.with=[]] Relations to eager load. @@ -535,30 +548,31 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { * * @method MongoDBAdapter#_find * @private - * @param {Object} mapper The mapper. + * @param {object} mapper The mapper. * @param {(string|number)} id Primary key of the record to retrieve. - * @param {Object} [opts] Configuration options. + * @param {object} [opts] Configuration options. + * @param {string|string[]|object} [opts.fields] Select a subset of fields to be returned. * @return {Promise} */ _find: function _find(mapper, id, opts) { - var self = this; + var _this7 = this; + opts || (opts = {}); opts.with || (opts.with = []); - var findOneOpts = self.getOpt('findOneOpts', opts); - findOneOpts.fields || (findOneOpts.fields = {}); + return this._run(function (client, success, failure) { + var collectionId = _this7._getCollectionId(mapper, opts); + var findOneOpts = _this7.getOpt('findOneOpts', opts); + findOneOpts.fields = _this7._getFields(mapper, opts); - return self.getClient().then(function (client) { - return new Promise(function (resolve, reject) { - var mongoQuery = {}; - mongoQuery[mapper.idAttribute] = self.toObjectID(mapper, id); - client.collection(mapper.table || underscore(mapper.name)).findOne(mongoQuery, findOneOpts, function (err, record) { - return err ? reject(err) : resolve(record); - }); + var mongoQuery = defineProperty({}, mapper.idAttribute, _this7.toObjectID(mapper, id)); + + client.collection(collectionId).findOne(mongoQuery, findOneOpts, function (err, record) { + return err ? failure(err) : success(record); }); }).then(function (record) { if (record) { - self._translateId(record, opts); + _this7._translateObjectIDs(record, opts); } return [record, {}]; }); @@ -569,10 +583,11 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { * Retrieve the records that match the selection query. * * @method MongoDBAdapter#findAll - * @param {Object} mapper The mapper. - * @param {Object} query Selection query. - * @param {Object} [opts] Configuration options. - * @param {Object} [opts.findOpts] Options to pass to collection#find. + * @param {object} mapper The mapper. + * @param {object} query Selection query. + * @param {object} [opts] Configuration options. + * @param {string|string[]|object} [opts.fields] Select a subset of fields to be returned. + * @param {object} [opts.findOpts] Options to pass to collection#find. * @param {boolean} [opts.raw=false] Whether to return a more detailed * response object. * @param {string[]} [opts.with=[]] Relations to eager load. @@ -585,44 +600,84 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { * * @method MongoDBAdapter#_findAll * @private - * @param {Object} mapper The mapper. - * @param {Object} query Selection query. - * @param {Object} [opts] Configuration options. + * @param {object} mapper The mapper. + * @param {object} query Selection query. + * @param {object} [opts] Configuration options. + * @param {string|string[]|object} [opts.fields] Select a subset of fields to be returned. * @return {Promise} */ _findAll: function _findAll(mapper, query, opts) { - var self = this; + var _this8 = this; + opts || (opts = {}); - var findOpts = self.getOpt('findOpts', opts); - jsData.utils.fillIn(findOpts, self.getQueryOptions(mapper, query)); - findOpts.fields || (findOpts.fields = {}); - var mongoQuery = self.getQuery(mapper, query); + return this._run(function (client, success, failure) { + var collectionId = _this8._getCollectionId(mapper, opts); + var findOpts = _this8.getOpt('findOpts', opts); + jsData.utils.fillIn(findOpts, _this8.getQueryOptions(mapper, query)); + findOpts.fields = _this8._getFields(mapper, opts); - return self.getClient().then(function (client) { - return new Promise(function (resolve, reject) { - client.collection(mapper.table || underscore(mapper.name)).find(mongoQuery, findOpts).toArray(function (err, records) { - return err ? reject(err) : resolve(records); - }); + var mongoQuery = _this8.getQuery(mapper, query); + + client.collection(collectionId).find(mongoQuery, findOpts).toArray(function (err, records) { + return err ? failure(err) : success(records); }); }).then(function (records) { - self._translateId(records, opts); + _this8._translateObjectIDs(records, opts); return [records, {}]; }); }, + _getCollectionId: function _getCollectionId(mapper, opts) { + opts || (opts = {}); + return opts.table || opts.collection || mapper.table || mapper.collection || underscore(mapper.name); + }, + _getFields: function _getFields(mapper, opts) { + opts || (opts = {}); + if (jsData.utils.isString(opts.fields)) { + opts.fields = defineProperty({}, opts.fields, 1); + } else if (jsData.utils.isArray(opts.fields)) { + var _ret = function () { + var fields = {}; + opts.fields.forEach(function (field) { + fields[field] = 1; + }); + return { + v: fields + }; + }(); + + if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v; + } + return opts.fields; + }, + _run: function _run(cb) { + var _this9 = this; + + if (this._db) { + // Use the cached db object + return new jsData.utils.Promise(function (resolve, reject) { + cb(_this9._db, resolve, reject); + }); + } + return this.getClient().then(function (client) { + return new jsData.utils.Promise(function (resolve, reject) { + cb(client, resolve, reject); + }); + }); + }, /** * Apply the given update to the record with the specified primary key. * * @method MongoDBAdapter#update - * @param {Object} mapper The mapper. + * @param {object} mapper The mapper. * @param {(string|number)} id The primary key of the record to be updated. - * @param {Object} props The update to apply to the record. - * @param {Object} [opts] Configuration options. + * @param {object} props The update to apply to the record. + * @param {object} [opts] Configuration options. * @param {boolean} [opts.raw=false] Whether to return a more detailed * response object. - * @param {Object} [opts.updateOpts] Options to pass to collection#update. + * @param {object} [opts.updateOpts] Options to pass to collection#update. * @return {Promise} */ @@ -632,36 +687,42 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { * * @method MongoDBAdapter#_update * @private - * @param {Object} mapper The mapper. + * @param {object} mapper The mapper. * @param {(string|number)} id The primary key of the record to be updated. - * @param {Object} props The update to apply to the record. - * @param {Object} [opts] Configuration options. + * @param {object} props The update to apply to the record. + * @param {object} [opts] Configuration options. * @return {Promise} */ _update: function _update(mapper, id, props, opts) { - var self = this; + var _this10 = this; + props || (props = {}); opts || (opts = {}); - var updateOpts = self.getOpt('updateOpts', opts); - return self.find(mapper, id, { raw: false }).then(function (record) { - if (!record) { + return this._find(mapper, id, { raw: false }).then(function (result) { + if (!result[0]) { throw new Error('Not Found'); } - return self.getClient().then(function (client) { - return new Promise(function (resolve, reject) { - var mongoQuery = {}; - mongoQuery[mapper.idAttribute] = self.toObjectID(mapper, id); - var collection = client.collection(mapper.table || underscore(mapper.name)); - collection[collection.updateOne ? 'updateOne' : 'update'](mongoQuery, { $set: props }, updateOpts, function (err, cursor) { - return err ? reject(err) : resolve(cursor); - }); - }); + return _this10._run(function (client, success, failure) { + var collectionId = _this10._getCollectionId(mapper, opts); + var updateOpts = _this10.getOpt('updateOpts', opts); + + var mongoQuery = defineProperty({}, mapper.idAttribute, _this10.toObjectID(mapper, id)); + var collection = client.collection(collectionId); + var handler = function handler(err, cursor) { + return err ? failure(err) : success(cursor); + }; + + if (collection.updateOne) { + collection.updateOne(mongoQuery, { $set: props }, updateOpts, handler); + } else { + collection.update(mongoQuery, { $set: props }, updateOpts, handler); + } }); }).then(function (cursor) { - return self.find(mapper, id, { raw: false }).then(function (record) { + return _this10._find(mapper, id, { raw: false }).then(function (result) { cursor.connection = undefined; - return [record, cursor]; + return [result[0], cursor]; }); }); }, @@ -671,13 +732,13 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { * Apply the given update to all records that match the selection query. * * @method MongoDBAdapter#updateAll - * @param {Object} mapper The mapper. - * @param {Object} props The update to apply to the selected records. - * @param {Object} [query] Selection query. - * @param {Object} [opts] Configuration options. + * @param {object} mapper The mapper. + * @param {object} props The update to apply to the selected records. + * @param {object} [query] Selection query. + * @param {object} [opts] Configuration options. * @param {boolean} [opts.raw=false] Whether to return a more detailed * response object. - * @param {Object} [opts.updateOpts] Options to pass to collection#update. + * @param {object} [opts.updateOpts] Options to pass to collection#update. * @return {Promise} */ @@ -694,42 +755,44 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { * @return {Promise} */ _updateAll: function _updateAll(mapper, props, query, opts) { - var self = this; + var _this11 = this; + props || (props = {}); query || (query = {}); opts || (opts = {}); var ids = void 0; - var updateOpts = self.getOpt('updateOpts', opts); - updateOpts.multi = true; - - return Promise.all([self.findAll(mapper, query, { raw: false }), self.getClient()]).then(function (results) { - var _results = babelHelpers.slicedToArray(results, 2); - var records = _results[0]; - var client = _results[1]; + return this._run(function (client, success, failure) { + return _this11._findAll(mapper, query, { raw: false }).then(function (result) { + var collectionId = _this11._getCollectionId(mapper, opts); + var updateOpts = _this11.getOpt('updateOpts', opts); + updateOpts.multi = true; - var queryOptions = self.getQueryOptions(mapper, query); - var mongoQuery = self.getQuery(mapper, query); + var queryOptions = _this11.getQueryOptions(mapper, query); + queryOptions.$set = props; + ids = result[0].map(function (record) { + return _this11.toObjectID(mapper, record[mapper.idAttribute]); + }); - queryOptions.$set = props; - ids = records.map(function (record) { - return self.toObjectID(mapper, record[mapper.idAttribute]); - }); + var mongoQuery = _this11.getQuery(mapper, query); + var collection = client.collection(collectionId); + var handler = function handler(err, cursor) { + return err ? failure(err) : success(cursor); + }; - return new Promise(function (resolve, reject) { - var collection = client.collection(mapper.table || underscore(mapper.name)); - collection[collection.updateMany ? 'updateMany' : 'update'](mongoQuery, queryOptions, updateOpts, function (err, cursor) { - return err ? reject(err) : resolve(cursor); - }); + if (collection.updateMany) { + collection.updateMany(mongoQuery, queryOptions, updateOpts, handler); + } else { + collection.update(mongoQuery, queryOptions, updateOpts, handler); + } }); }).then(function (cursor) { - var query = {}; - query[mapper.idAttribute] = { + var query = defineProperty({}, mapper.idAttribute, { 'in': ids - }; - return self.findAll(mapper, query, { raw: false }).then(function (records) { + }); + return _this11._findAll(mapper, query, { raw: false }).then(function (result) { cursor.connection = undefined; - return [records, cursor]; + return [result[0], cursor]; }); }); }, @@ -742,7 +805,7 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { * Useful when you need to do anything custom with the MongoDB client library. * * @method MongoDBAdapter#getClient - * @return {Object} MongoDB client. + * @return {object} MongoDB client. */ getClient: function getClient() { return this.client; @@ -758,7 +821,7 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { * - and bunch of filtering operators * * @method MongoDBAdapter#getQuery - * @return {Object} + * @return {object} */ getQuery: function getQuery(mapper, query) { query = jsData.utils.plainCopy(query || {}); @@ -883,7 +946,7 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { * - orderBy/sort * * @method MongoDBAdapter#getQueryOptions - * @return {Object} + * @return {object} */ getQueryOptions: function getQueryOptions(mapper, query) { query = jsData.utils.plainCopy(query || {}); @@ -950,11 +1013,12 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { * @return {*} */ makeHasManyLocalKeys: function makeHasManyLocalKeys(mapper, def, record) { - var self = this; + var _this12 = this; + var relatedMapper = def.getRelation(); - var localKeys = jsDataAdapter.Adapter.prototype.makeHasManyLocalKeys.call(self, mapper, def, record); + var localKeys = jsDataAdapter.Adapter.prototype.makeHasManyLocalKeys.call(this, mapper, def, record); return localKeys.map(function (key) { - return self.toObjectID(relatedMapper, key); + return _this12.toObjectID(relatedMapper, key); }); }, @@ -972,8 +1036,12 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { /** * Details of the current version of the `js-data-mongodb` module. * + * @example + * import {version} from 'js-data-mongodb' + * console.log(version.full) + * * @name module:js-data-mongodb.version - * @type {Object} + * @type {object} * @property {string} version.full The full semver value. * @property {number} version.major The major version number. * @property {number} version.minor The minor version number. @@ -984,14 +1052,94 @@ jsData.utils.addHiddenPropsToTarget(MongoDBAdapter.prototype, { * otherwise `false` if the current version is not beta. */ var version = { - beta: 1, - full: '1.0.0-beta.1', + full: '1.0.0-rc.1', major: 1, minor: 0, patch: 0 }; +/** + * {@link MongoDBAdapter} class. + * + * @example + * import {MongoDBAdapter} from 'js-data-mongodb' + * const adapter = new MongoDBAdapter() + * + * @name module:js-data-mongodb.MongoDBAdapter + * @see MongoDBAdapter + * @type {Constructor} + */ + +/** + * Registered as `js-data-mongodb` in NPM. + * + * @example Install from NPM + * npm i --save js-data-mongodb@rc js-data@rc mongodb bson + * + * @example Load via CommonJS + * var MongoDBAdapter = require('js-data-mongodb').MongoDBAdapter + * var adapter = new MongoDBAdapter() + * + * @example Load via ES2015 Modules + * import {MongoDBAdapter} from 'js-data-mongodb' + * const adapter = new MongoDBAdapter() + * + * @module js-data-mongodb + */ + +/** +* Create a subclass of this MongoDBAdapter: +* @example MongoDBAdapter.extend +* // Normally you would do: import { MongoDBAdapter } from 'js-data-mongodb' +* const JSDataMongoDB = require('js-data-mongodb') +* const { MongoDBAdapter } = JSDataMongoDB +* console.log('Using JSDataMongoDB v' + JSDataMongoDB.version.full) +* +* // Extend the class using ES2015 class syntax. +* class CustomMongoDBAdapterClass extends MongoDBAdapter { +* foo () { return 'bar' } +* static beep () { return 'boop' } +* } +* const customMongoDBAdapter = new CustomMongoDBAdapterClass() +* console.log(customMongoDBAdapter.foo()) +* console.log(CustomMongoDBAdapterClass.beep()) +* +* // Extend the class using alternate method. +* const OtherMongoDBAdapterClass = MongoDBAdapter.extend({ +* foo () { return 'bar' } +* }, { +* beep () { return 'boop' } +* }) +* const otherMongoDBAdapter = new OtherMongoDBAdapterClass() +* console.log(otherMongoDBAdapter.foo()) +* console.log(OtherMongoDBAdapterClass.beep()) +* +* // Extend the class, providing a custom constructor. +* function AnotherMongoDBAdapterClass () { +* MongoDBAdapter.call(this) +* this.created_at = new Date().getTime() +* } +* MongoDBAdapter.extend({ +* constructor: AnotherMongoDBAdapterClass, +* foo () { return 'bar' } +* }, { +* beep () { return 'boop' } +* }) +* const anotherMongoDBAdapter = new AnotherMongoDBAdapterClass() +* console.log(anotherMongoDBAdapter.created_at) +* console.log(anotherMongoDBAdapter.foo()) +* console.log(AnotherMongoDBAdapterClass.beep()) +* +* @method MongoDBAdapter.extend +* @param {object} [props={}] Properties to add to the prototype of the +* subclass. +* @param {object} [props.constructor] Provide a custom constructor function +* to be used as the subclass itself. +* @param {object} [classProps={}] Static properties to add to the subclass. +* @returns {Constructor} Subclass of this MongoDBAdapter class. +* @since 3.0.0 +*/ + exports.MongoDBAdapter = MongoDBAdapter; exports.version = version; -exports['default'] = MongoDBAdapter; -//# sourceMappingURL=js-data-mongodb.js.map \ No newline at end of file +//# sourceMappingURL=js-data-mongodb.js.map diff --git a/dist/js-data-mongodb.js.map b/dist/js-data-mongodb.js.map index ad73269..bc0199a 100644 --- a/dist/js-data-mongodb.js.map +++ b/dist/js-data-mongodb.js.map @@ -1 +1 @@ -{"version":3,"file":"js-data-mongodb.js","sources":["../src/index.js"],"sourcesContent":["import {MongoClient} from 'mongodb'\nimport {ObjectID} from 'bson'\nimport {utils} from 'js-data'\nimport {\n Adapter,\n reserved\n} from 'js-data-adapter'\nimport underscore from 'mout/string/underscore'\n\nconst DEFAULTS = {\n /**\n * Convert ObjectIDs to strings when pulling records out of the database.\n *\n * @name MongoDBAdapter#translateId\n * @type {boolean}\n * @default true\n */\n translateId: true,\n\n /**\n * MongoDB URI.\n *\n * @name MongoDBAdapter#uri\n * @type {string}\n * @default mongodb://localhost:27017\n */\n uri: 'mongodb://localhost:27017'\n}\n\nconst COUNT_OPTS_DEFAULTS = {}\nconst FIND_OPTS_DEFAULTS = {}\nconst FIND_ONE_OPTS_DEFAULTS = {}\nconst INSERT_OPTS_DEFAULTS = {}\nconst INSERT_MANY_OPTS_DEFAULTS = {}\nconst UPDATE_OPTS_DEFAULTS = {}\nconst REMOVE_OPTS_DEFAULTS = {}\n\n/**\n * MongoDBAdapter class.\n *\n * @example\n * // Use Container instead of DataStore on the server\n * import {Container} from 'js-data'\n * import MongoDBAdapter from 'js-data-mongodb'\n *\n * // Create a store to hold your Mappers\n * const store = new Container({\n * mapperDefaults: {\n * // MongoDB uses \"_id\" as the primary key\n * idAttribute: '_id'\n * }\n * })\n *\n * // Create an instance of MongoDBAdapter with default settings\n * const adapter = new MongoDBAdapter()\n *\n * // Mappers in \"store\" will use the MongoDB adapter by default\n * store.registerAdapter('mongodb', adapter, { default: true })\n *\n * // Create a Mapper that maps to a \"user\" collection\n * store.defineMapper('user')\n *\n * @class MongoDBAdapter\n * @extends Adapter\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.debug=false] See {@link Adapter#debug}.\n * @param {Object} [opts.countOpts] See {@link MongoDBAdapter#countOpts}.\n * @param {Object} [opts.findOpts] See {@link MongoDBAdapter#findOpts}.\n * @param {Object} [opts.findOneOpts] See {@link MongoDBAdapter#findOneOpts}.\n * @param {Object} [opts.insertOpts] See {@link MongoDBAdapter#insertOpts}.\n * @param {Object} [opts.insertManyOpts] See {@link MongoDBAdapter#insertManyOpts}.\n * @param {boolean} [opts.raw=false] See {@link Adapter#raw}.\n * @param {Object} [opts.removeOpts] See {@link MongoDBAdapter#removeOpts}.\n * @param {boolean} [opts.translateId=true] See {@link MongoDBAdapter#translateId}.\n * @param {Object} [opts.updateOpts] See {@link MongoDBAdapter#updateOpts}.\n * @param {string} [opts.uri=\"mongodb://localhost:27017\"] See {@link MongoDBAdapter#uri}.\n */\nexport function MongoDBAdapter (opts) {\n const self = this\n utils.classCallCheck(self, MongoDBAdapter)\n opts || (opts = {})\n if (utils.isString(opts)) {\n opts = { uri: opts }\n }\n utils.fillIn(opts, DEFAULTS)\n Adapter.call(self, opts)\n\n /**\n * Default options to pass to collection#count.\n *\n * @name MongoDBAdapter#countOpts\n * @type {Object}\n * @default {}\n */\n self.countOpts || (self.countOpts = {})\n utils.fillIn(self.countOpts, COUNT_OPTS_DEFAULTS)\n\n /**\n * Default options to pass to collection#find.\n *\n * @name MongoDBAdapter#findOpts\n * @type {Object}\n * @default {}\n */\n self.findOpts || (self.findOpts = {})\n utils.fillIn(self.findOpts, FIND_OPTS_DEFAULTS)\n\n /**\n * Default options to pass to collection#findOne.\n *\n * @name MongoDBAdapter#findOneOpts\n * @type {Object}\n * @default {}\n */\n self.findOneOpts || (self.findOneOpts = {})\n utils.fillIn(self.findOneOpts, FIND_ONE_OPTS_DEFAULTS)\n\n /**\n * Default options to pass to collection#insert.\n *\n * @name MongoDBAdapter#insertOpts\n * @type {Object}\n * @default {}\n */\n self.insertOpts || (self.insertOpts = {})\n utils.fillIn(self.insertOpts, INSERT_OPTS_DEFAULTS)\n\n /**\n * Default options to pass to collection#insertMany.\n *\n * @name MongoDBAdapter#insertManyOpts\n * @type {Object}\n * @default {}\n */\n self.insertManyOpts || (self.insertManyOpts = {})\n utils.fillIn(self.insertManyOpts, INSERT_MANY_OPTS_DEFAULTS)\n\n /**\n * Default options to pass to collection#update.\n *\n * @name MongoDBAdapter#updateOpts\n * @type {Object}\n * @default {}\n */\n self.updateOpts || (self.updateOpts = {})\n utils.fillIn(self.updateOpts, UPDATE_OPTS_DEFAULTS)\n\n /**\n * Default options to pass to collection#update.\n *\n * @name MongoDBAdapter#removeOpts\n * @type {Object}\n * @default {}\n */\n self.removeOpts || (self.removeOpts = {})\n utils.fillIn(self.removeOpts, REMOVE_OPTS_DEFAULTS)\n\n /**\n * A Promise that resolves to a reference to the MongoDB client being used by\n * this adapter.\n *\n * @name MongoDBAdapter#client\n * @type {Object}\n */\n self.client = new Promise(function (resolve, reject) {\n MongoClient.connect(opts.uri, function (err, db) {\n return err ? reject(err) : resolve(db)\n })\n })\n}\n\n// Setup prototype inheritance from Adapter\nMongoDBAdapter.prototype = Object.create(Adapter.prototype, {\n constructor: {\n value: MongoDBAdapter,\n enumerable: false,\n writable: true,\n configurable: true\n }\n})\n\nObject.defineProperty(MongoDBAdapter, '__super__', {\n configurable: true,\n value: Adapter\n})\n\n/**\n * Alternative to ES6 class syntax for extending `MongoDBAdapter`.\n *\n * @example Using the ES2015 class syntax.\n * class MyMongoDBAdapter extends MongoDBAdapter {...}\n * const adapter = new MyMongoDBAdapter()\n *\n * @example Using {@link MongoDBAdapter.extend}.\n * var instanceProps = {...}\n * var classProps = {...}\n *\n * var MyMongoDBAdapter = MongoDBAdapter.extend(instanceProps, classProps)\n * var adapter = new MyMongoDBAdapter()\n *\n * @method MongoDBAdapter.extend\n * @static\n * @param {Object} [instanceProps] Properties that will be added to the\n * prototype of the subclass.\n * @param {Object} [classProps] Properties that will be added as static\n * properties to the subclass itself.\n * @return {Object} Subclass of `MongoDBAdapter`.\n */\nMongoDBAdapter.extend = utils.extend\n\nutils.addHiddenPropsToTarget(MongoDBAdapter.prototype, {\n /**\n * Translate ObjectIDs to strings.\n *\n * @method MongoDBAdapter#_translateId\n * @return {*}\n */\n _translateId (r, opts) {\n opts || (opts = {})\n if (this.getOpt('translateId', opts)) {\n if (utils.isArray(r)) {\n r.forEach(function (_r) {\n const __id = _r._id ? _r._id.toString() : _r._id\n _r._id = typeof __id === 'string' ? __id : _r._id\n })\n } else if (utils.isObject(r)) {\n const __id = r._id ? r._id.toString() : r._id\n r._id = typeof __id === 'string' ? __id : r._id\n }\n }\n return r\n },\n\n /**\n * Retrieve the number of records that match the selection query.\n *\n * @method MongoDBAdapter#count\n * @param {Object} mapper The mapper.\n * @param {Object} query Selection query.\n * @param {Object} [opts] Configuration options.\n * @param {Object} [opts.countOpts] Options to pass to collection#count.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * response object.\n * @param {string[]} [opts.with=[]] Relations to eager load.\n * @return {Promise}\n */\n\n /**\n * Retrieve the records that match the selection query. Internal method used\n * by Adapter#count.\n *\n * @method MongoDBAdapter#_count\n * @private\n * @param {Object} mapper The mapper.\n * @param {Object} query Selection query.\n * @param {Object} [opts] Configuration options.\n * @return {Promise}\n */\n _count (mapper, query, opts) {\n const self = this\n opts || (opts = {})\n\n const countOpts = self.getOpt('countOpts', opts)\n utils.fillIn(countOpts, self.getQueryOptions(mapper, query))\n const mongoQuery = self.getQuery(mapper, query)\n\n return self.getClient().then(function (client) {\n return new Promise(function (resolve, reject) {\n client.collection(mapper.table || underscore(mapper.name)).count(mongoQuery, countOpts, function (err, count) {\n return err ? reject(err) : resolve([count, {}])\n })\n })\n })\n },\n\n /**\n * Create a new record.\n *\n * @method MongoDBAdapter#create\n * @param {Object} mapper The mapper.\n * @param {Object} props The record to be created.\n * @param {Object} [opts] Configuration options.\n * @param {Object} [opts.insertOpts] Options to pass to collection#insert.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * @return {Promise}\n */\n\n /**\n * Create a new record. Internal method used by Adapter#create.\n *\n * @method MongoDBAdapter#_create\n * @private\n * @param {Object} mapper The mapper.\n * @param {Object} props The record to be created.\n * @param {Object} [opts] Configuration options.\n * @return {Promise}\n */\n _create (mapper, props, opts) {\n const self = this\n props || (props = {})\n opts || (opts = {})\n props = utils.plainCopy(props)\n\n const insertOpts = self.getOpt('insertOpts', opts)\n\n return self.getClient().then(function (client) {\n return new Promise(function (resolve, reject) {\n const collection = client.collection(mapper.table || underscore(mapper.name))\n const method = collection.insertOne ? 'insertOne' : 'insert'\n collection[method](props, insertOpts, function (err, cursor) {\n return err ? reject(err) : resolve(cursor)\n })\n })\n }).then(function (cursor) {\n let record\n let r = cursor.ops ? cursor.ops : cursor\n self._translateId(r, opts)\n record = utils.isArray(r) ? r[0] : r\n cursor.connection = undefined\n return [record, cursor]\n })\n },\n\n /**\n * Create multiple records in a single batch.\n *\n * @method MongoDBAdapter#createMany\n * @param {Object} mapper The mapper.\n * @param {Object} props The records to be created.\n * @param {Object} [opts] Configuration options.\n * @param {Object} [opts.insertManyOpts] Options to pass to\n * collection#insertMany.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * response object.\n * @return {Promise}\n */\n\n /**\n * Create multiple records in a single batch. Internal method used by\n * Adapter#createMany.\n *\n * @method MongoDBAdapter#_createMany\n * @private\n * @param {Object} mapper The mapper.\n * @param {Object} props The records to be created.\n * @param {Object} [opts] Configuration options.\n * @return {Promise}\n */\n _createMany (mapper, props, opts) {\n const self = this\n props || (props = {})\n opts || (opts = {})\n props = utils.plainCopy(props)\n\n const insertManyOpts = self.getOpt('insertManyOpts', opts)\n\n return self.getClient().then(function (client) {\n return new Promise(function (resolve, reject) {\n const collection = client.collection(mapper.table || underscore(mapper.name))\n collection.insertMany(props, insertManyOpts, function (err, cursor) {\n return err ? reject(err) : resolve(cursor)\n })\n })\n }).then(function (cursor) {\n let records = []\n let r = cursor.ops ? cursor.ops : cursor\n self._translateId(r, opts)\n records = r\n cursor.connection = undefined\n return [records, cursor]\n })\n },\n\n /**\n * Destroy the record with the given primary key.\n *\n * @method MongoDBAdapter#destroy\n * @param {Object} mapper The mapper.\n * @param {(string|number)} id Primary key of the record to destroy.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * response object.\n * @param {Object} [opts.removeOpts] Options to pass to collection#remove.\n * @return {Promise}\n */\n\n /**\n * Destroy the record with the given primary key. Internal method used by\n * Adapter#destroy.\n *\n * @method MongoDBAdapter#_destroy\n * @private\n * @param {Object} mapper The mapper.\n * @param {(string|number)} id Primary key of the record to destroy.\n * @param {Object} [opts] Configuration options.\n * @return {Promise}\n */\n _destroy (mapper, id, opts) {\n const self = this\n opts || (opts = {})\n const removeOpts = self.getOpt('removeOpts', opts)\n\n return self.getClient().then(function (client) {\n return new Promise(function (resolve, reject) {\n const mongoQuery = {}\n mongoQuery[mapper.idAttribute] = self.toObjectID(mapper, id)\n const collection = client.collection(mapper.table || underscore(mapper.name))\n collection[collection.deleteOne ? 'deleteOne' : 'remove'](mongoQuery, removeOpts, function (err, cursor) {\n return err ? reject(err) : resolve(cursor)\n })\n })\n }).then(function (cursor) {\n return [undefined, cursor]\n })\n },\n\n /**\n * Destroy the records that match the selection query.\n *\n * @method MongoDBAdapter#destroyAll\n * @param {Object} mapper the mapper.\n * @param {Object} [query] Selection query.\n * @param {Object} [query.where] Filtering criteria.\n * @param {string|Array} [query.orderBy] Sorting criteria.\n * @param {string|Array} [query.sort] Same as `query.sort`.\n * @param {number} [query.limit] Limit results.\n * @param {number} [query.skip] Offset results.\n * @param {number} [query.offset] Same as `query.skip`.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * response object.\n * @param {Object} [opts.removeOpts] Options to pass to collection#remove.\n * @return {Promise}\n */\n\n /**\n * Destroy the records that match the selection query. Internal method used by\n * Adapter#destroyAll.\n *\n * @method MongoDBAdapter#_destroyAll\n * @private\n * @param {Object} mapper the mapper.\n * @param {Object} [query] Selection query.\n * @param {Object} [opts] Configuration options.\n * @return {Promise}\n */\n _destroyAll (mapper, query, opts) {\n const self = this\n query || (query = {})\n opts || (opts = {})\n const removeOpts = self.getOpt('removeOpts', opts)\n utils.fillIn(removeOpts, self.getQueryOptions(mapper, query))\n\n return self.getClient().then(function (client) {\n const mongoQuery = self.getQuery(mapper, query)\n return new Promise(function (resolve, reject) {\n const collection = client.collection(mapper.table || underscore(mapper.name))\n collection[collection.deleteMany ? 'deleteMany' : 'remove'](mongoQuery, removeOpts, function (err, cursor) {\n return err ? reject(err) : resolve(cursor)\n })\n })\n }).then(function (cursor) {\n cursor.connection = undefined\n return [undefined, cursor]\n })\n },\n\n /**\n * Retrieve the record with the given primary key.\n *\n * @method MongoDBAdapter#find\n * @param {Object} mapper The mapper.\n * @param {(string|number)} id Primary key of the record to retrieve.\n * @param {Object} [opts] Configuration options.\n * @param {Object} [opts.findOneOpts] Options to pass to collection#findOne.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * response object.\n * @param {string[]} [opts.with=[]] Relations to eager load.\n * @return {Promise}\n */\n\n /**\n * Retrieve the record with the given primary key. Internal method used by\n * Adapter#find.\n *\n * @method MongoDBAdapter#_find\n * @private\n * @param {Object} mapper The mapper.\n * @param {(string|number)} id Primary key of the record to retrieve.\n * @param {Object} [opts] Configuration options.\n * @return {Promise}\n */\n _find (mapper, id, opts) {\n const self = this\n opts || (opts = {})\n opts.with || (opts.with = [])\n\n const findOneOpts = self.getOpt('findOneOpts', opts)\n findOneOpts.fields || (findOneOpts.fields = {})\n\n return self.getClient().then(function (client) {\n return new Promise(function (resolve, reject) {\n let mongoQuery = {}\n mongoQuery[mapper.idAttribute] = self.toObjectID(mapper, id)\n client.collection(mapper.table || underscore(mapper.name)).findOne(mongoQuery, findOneOpts, function (err, record) {\n return err ? reject(err) : resolve(record)\n })\n })\n }).then(function (record) {\n if (record) {\n self._translateId(record, opts)\n }\n return [record, {}]\n })\n },\n\n /**\n * Retrieve the records that match the selection query.\n *\n * @method MongoDBAdapter#findAll\n * @param {Object} mapper The mapper.\n * @param {Object} query Selection query.\n * @param {Object} [opts] Configuration options.\n * @param {Object} [opts.findOpts] Options to pass to collection#find.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * response object.\n * @param {string[]} [opts.with=[]] Relations to eager load.\n * @return {Promise}\n */\n\n /**\n * Retrieve the records that match the selection query. Internal method used\n * by Adapter#findAll.\n *\n * @method MongoDBAdapter#_findAll\n * @private\n * @param {Object} mapper The mapper.\n * @param {Object} query Selection query.\n * @param {Object} [opts] Configuration options.\n * @return {Promise}\n */\n _findAll (mapper, query, opts) {\n const self = this\n opts || (opts = {})\n\n const findOpts = self.getOpt('findOpts', opts)\n utils.fillIn(findOpts, self.getQueryOptions(mapper, query))\n findOpts.fields || (findOpts.fields = {})\n const mongoQuery = self.getQuery(mapper, query)\n\n return self.getClient().then(function (client) {\n return new Promise(function (resolve, reject) {\n client.collection(mapper.table || underscore(mapper.name)).find(mongoQuery, findOpts).toArray(function (err, records) {\n return err ? reject(err) : resolve(records)\n })\n })\n }).then(function (records) {\n self._translateId(records, opts)\n return [records, {}]\n })\n },\n\n /**\n * Apply the given update to the record with the specified primary key.\n *\n * @method MongoDBAdapter#update\n * @param {Object} mapper The mapper.\n * @param {(string|number)} id The primary key of the record to be updated.\n * @param {Object} props The update to apply to the record.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * response object.\n * @param {Object} [opts.updateOpts] Options to pass to collection#update.\n * @return {Promise}\n */\n\n /**\n * Apply the given update to the record with the specified primary key.\n * Internal method used by Adapter#update.\n *\n * @method MongoDBAdapter#_update\n * @private\n * @param {Object} mapper The mapper.\n * @param {(string|number)} id The primary key of the record to be updated.\n * @param {Object} props The update to apply to the record.\n * @param {Object} [opts] Configuration options.\n * @return {Promise}\n */\n _update (mapper, id, props, opts) {\n const self = this\n props || (props = {})\n opts || (opts = {})\n const updateOpts = self.getOpt('updateOpts', opts)\n\n return self.find(mapper, id, { raw: false }).then(function (record) {\n if (!record) {\n throw new Error('Not Found')\n }\n return self.getClient().then(function (client) {\n return new Promise(function (resolve, reject) {\n const mongoQuery = {}\n mongoQuery[mapper.idAttribute] = self.toObjectID(mapper, id)\n const collection = client.collection(mapper.table || underscore(mapper.name))\n collection[collection.updateOne ? 'updateOne' : 'update'](mongoQuery, { $set: props }, updateOpts, function (err, cursor) {\n return err ? reject(err) : resolve(cursor)\n })\n })\n })\n }).then(function (cursor) {\n return self.find(mapper, id, { raw: false }).then(function (record) {\n cursor.connection = undefined\n return [record, cursor]\n })\n })\n },\n\n /**\n * Apply the given update to all records that match the selection query.\n *\n * @method MongoDBAdapter#updateAll\n * @param {Object} mapper The mapper.\n * @param {Object} props The update to apply to the selected records.\n * @param {Object} [query] Selection query.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * response object.\n * @param {Object} [opts.updateOpts] Options to pass to collection#update.\n * @return {Promise}\n */\n\n /**\n * Apply the given update to all records that match the selection query.\n * Internal method used by Adapter#updateAll.\n *\n * @method MongoDBAdapter#_updateAll\n * @private\n * @param {Object} mapper The mapper.\n * @param {Object} props The update to apply to the selected records.\n * @param {Object} [query] Selection query.\n * @param {Object} [opts] Configuration options.\n * @return {Promise}\n */\n _updateAll (mapper, props, query, opts) {\n const self = this\n props || (props = {})\n query || (query = {})\n opts || (opts = {})\n let ids\n const updateOpts = self.getOpt('updateOpts', opts)\n updateOpts.multi = true\n\n return Promise.all([\n self.findAll(mapper, query, { raw: false }),\n self.getClient()\n ]).then(function (results) {\n let [records, client] = results\n const queryOptions = self.getQueryOptions(mapper, query)\n const mongoQuery = self.getQuery(mapper, query)\n\n queryOptions.$set = props\n ids = records.map(function (record) {\n return self.toObjectID(mapper, record[mapper.idAttribute])\n })\n\n return new Promise(function (resolve, reject) {\n const collection = client.collection(mapper.table || underscore(mapper.name))\n collection[collection.updateMany ? 'updateMany' : 'update'](mongoQuery, queryOptions, updateOpts, function (err, cursor) {\n return err ? reject(err) : resolve(cursor)\n })\n })\n }).then(function (cursor) {\n const query = {}\n query[mapper.idAttribute] = {\n 'in': ids\n }\n return self.findAll(mapper, query, { raw: false }).then(function (records) {\n cursor.connection = undefined\n return [records, cursor]\n })\n })\n },\n\n /**\n * Return a Promise that resolves to a reference to the MongoDB client being\n * used by this adapter.\n *\n * Useful when you need to do anything custom with the MongoDB client library.\n *\n * @method MongoDBAdapter#getClient\n * @return {Object} MongoDB client.\n */\n getClient () {\n return this.client\n },\n\n /**\n * Map filtering params in a selection query to MongoDB a filtering object.\n *\n * Handles the following:\n *\n * - where\n * - and bunch of filtering operators\n *\n * @method MongoDBAdapter#getQuery\n * @return {Object}\n */\n getQuery (mapper, query) {\n query = utils.plainCopy(query || {})\n query.where || (query.where = {})\n\n utils.forOwn(query, function (config, keyword) {\n if (reserved.indexOf(keyword) === -1) {\n if (utils.isObject(config)) {\n query.where[keyword] = config\n } else {\n query.where[keyword] = {\n '==': config\n }\n }\n delete query[keyword]\n }\n })\n\n let mongoQuery = {}\n\n if (Object.keys(query.where).length !== 0) {\n utils.forOwn(query.where, function (criteria, field) {\n if (!utils.isObject(criteria)) {\n query.where[field] = {\n '==': criteria\n }\n }\n utils.forOwn(criteria, function (v, op) {\n if (op === '==' || op === '===' || op === 'contains') {\n mongoQuery[field] = v\n } else if (op === '!=' || op === '!==' || op === 'notContains') {\n mongoQuery[field] = mongoQuery[field] || {}\n mongoQuery[field].$ne = v\n } else if (op === '>') {\n mongoQuery[field] = mongoQuery[field] || {}\n mongoQuery[field].$gt = v\n } else if (op === '>=') {\n mongoQuery[field] = mongoQuery[field] || {}\n mongoQuery[field].$gte = v\n } else if (op === '<') {\n mongoQuery[field] = mongoQuery[field] || {}\n mongoQuery[field].$lt = v\n } else if (op === '<=') {\n mongoQuery[field] = mongoQuery[field] || {}\n mongoQuery[field].$lte = v\n } else if (op === 'in') {\n mongoQuery[field] = mongoQuery[field] || {}\n mongoQuery[field].$in = v\n } else if (op === 'notIn') {\n mongoQuery[field] = mongoQuery[field] || {}\n mongoQuery[field].$nin = v\n } else if (op === '|==' || op === '|===' || op === '|contains') {\n mongoQuery.$or = mongoQuery.$or || []\n let orEqQuery = {}\n orEqQuery[field] = v\n mongoQuery.$or.push(orEqQuery)\n } else if (op === '|!=' || op === '|!==' || op === '|notContains') {\n mongoQuery.$or = mongoQuery.$or || []\n let orNeQuery = {}\n orNeQuery[field] = {\n '$ne': v\n }\n mongoQuery.$or.push(orNeQuery)\n } else if (op === '|>') {\n mongoQuery.$or = mongoQuery.$or || []\n let orGtQuery = {}\n orGtQuery[field] = {\n '$gt': v\n }\n mongoQuery.$or.push(orGtQuery)\n } else if (op === '|>=') {\n mongoQuery.$or = mongoQuery.$or || []\n let orGteQuery = {}\n orGteQuery[field] = {\n '$gte': v\n }\n mongoQuery.$or.push(orGteQuery)\n } else if (op === '|<') {\n mongoQuery.$or = mongoQuery.$or || []\n let orLtQuery = {}\n orLtQuery[field] = {\n '$lt': v\n }\n mongoQuery.$or.push(orLtQuery)\n } else if (op === '|<=') {\n mongoQuery.$or = mongoQuery.$or || []\n let orLteQuery = {}\n orLteQuery[field] = {\n '$lte': v\n }\n mongoQuery.$or.push(orLteQuery)\n } else if (op === '|in') {\n mongoQuery.$or = mongoQuery.$or || []\n let orInQuery = {}\n orInQuery[field] = {\n '$in': v\n }\n mongoQuery.$or.push(orInQuery)\n } else if (op === '|notIn') {\n mongoQuery.$or = mongoQuery.$or || []\n let orNinQuery = {}\n orNinQuery[field] = {\n '$nin': v\n }\n mongoQuery.$or.push(orNinQuery)\n }\n })\n })\n }\n\n return mongoQuery\n },\n\n /**\n * Map non-filtering params in a selection query to MongoDB query options.\n *\n * Handles the following:\n *\n * - limit\n * - skip/offset\n * - orderBy/sort\n *\n * @method MongoDBAdapter#getQueryOptions\n * @return {Object}\n */\n getQueryOptions (mapper, query) {\n query = utils.plainCopy(query || {})\n query.orderBy = query.orderBy || query.sort\n query.skip = query.skip || query.offset\n\n let queryOptions = {}\n\n if (query.orderBy) {\n if (utils.isString(query.orderBy)) {\n query.orderBy = [\n [query.orderBy, 'asc']\n ]\n }\n for (var i = 0; i < query.orderBy.length; i++) {\n if (utils.isString(query.orderBy[i])) {\n query.orderBy[i] = [query.orderBy[i], 'asc']\n }\n }\n queryOptions.sort = query.orderBy\n }\n\n if (query.skip) {\n queryOptions.skip = +query.skip\n }\n\n if (query.limit) {\n queryOptions.limit = +query.limit\n }\n\n return queryOptions\n },\n\n /**\n * Turn an _id into an ObjectID if it isn't already an ObjectID.\n *\n * @method MongoDBAdapter#toObjectID\n * @return {*}\n */\n toObjectID (mapper, id) {\n if (id !== undefined && mapper.idAttribute === '_id' && typeof id === 'string' && ObjectID.isValid(id) && !(id instanceof ObjectID)) {\n return new ObjectID(id)\n }\n return id\n },\n\n /**\n * Return the foreignKey from the given record for the provided relationship.\n *\n * @method MongoDBAdapter#makeBelongsToForeignKey\n * @return {*}\n */\n makeBelongsToForeignKey (mapper, def, record) {\n return this.toObjectID(def.getRelation(), Adapter.prototype.makeBelongsToForeignKey.call(this, mapper, def, record))\n },\n\n /**\n * Return the localKeys from the given record for the provided relationship.\n *\n * Override with care.\n *\n * @method MongoDBAdapter#makeHasManyLocalKeys\n * @return {*}\n */\n makeHasManyLocalKeys (mapper, def, record) {\n const self = this\n const relatedMapper = def.getRelation()\n const localKeys = Adapter.prototype.makeHasManyLocalKeys.call(self, mapper, def, record)\n return localKeys.map(function (key) {\n return self.toObjectID(relatedMapper, key)\n })\n },\n\n /**\n * Not supported.\n *\n * @method MongoDBAdapter#updateMany\n */\n updateMany () {\n throw new Error('not supported!')\n }\n})\n\n/**\n * Details of the current version of the `js-data-mongodb` module.\n *\n * @name module:js-data-mongodb.version\n * @type {Object}\n * @property {string} version.full The full semver value.\n * @property {number} version.major The major version number.\n * @property {number} version.minor The minor version number.\n * @property {number} version.patch The patch version number.\n * @property {(string|boolean)} version.alpha The alpha version value,\n * otherwise `false` if the current version is not alpha.\n * @property {(string|boolean)} version.beta The beta version value,\n * otherwise `false` if the current version is not beta.\n */\nexport const version = '<%= version %>'\n\nexport default MongoDBAdapter\n"],"names":["utils","Adapter","reserved","ObjectID"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":null,"sources":["../src/index.js"],"sourcesContent":["import {MongoClient} from 'mongodb'\nimport {ObjectID} from 'bson'\nimport {utils} from 'js-data'\nimport {\n Adapter,\n reserved\n} from 'js-data-adapter'\nimport underscore from 'mout/string/underscore'\n\nconst DEFAULTS = {\n /**\n * Convert ObjectIDs to strings when pulling records out of the database.\n *\n * @name MongoDBAdapter#translateId\n * @type {boolean}\n * @default true\n */\n translateId: true,\n /**\n * Convert fields of record from databse that are ObjectIDs to strings\n * @type {Boolean}\n * @default false\n */\n translateObjectIDs: false,\n\n /**\n * MongoDB URI.\n *\n * @name MongoDBAdapter#uri\n * @type {string}\n * @default mongodb://localhost:27017\n */\n uri: 'mongodb://localhost:27017'\n}\n\nconst COUNT_OPTS_DEFAULTS = {}\nconst FIND_OPTS_DEFAULTS = {}\nconst FIND_ONE_OPTS_DEFAULTS = {}\nconst INSERT_OPTS_DEFAULTS = {}\nconst INSERT_MANY_OPTS_DEFAULTS = {}\nconst UPDATE_OPTS_DEFAULTS = {}\nconst REMOVE_OPTS_DEFAULTS = {}\n\n/**\n * MongoDBAdapter class.\n *\n * @example\n * // Use Container instead of DataStore on the server\n * import {Container} from 'js-data'\n * import MongoDBAdapter from 'js-data-mongodb'\n *\n * // Create a store to hold your Mappers\n * const store = new Container({\n * mapperDefaults: {\n * // MongoDB uses \"_id\" as the primary key\n * idAttribute: '_id'\n * }\n * })\n *\n * // Create an instance of MongoDBAdapter with default settings\n * const adapter = new MongoDBAdapter()\n *\n * // Mappers in \"store\" will use the MongoDB adapter by default\n * store.registerAdapter('mongodb', adapter, { default: true })\n *\n * // Create a Mapper that maps to a \"user\" collection\n * store.defineMapper('user')\n *\n * @class MongoDBAdapter\n * @extends Adapter\n * @param {object} [opts] Configuration options.\n * @param {boolean} [opts.debug=false] See {@link Adapter#debug}.\n * @param {object} [opts.countOpts] See {@link MongoDBAdapter#countOpts}.\n * @param {object} [opts.findOpts] See {@link MongoDBAdapter#findOpts}.\n * @param {object} [opts.findOneOpts] See {@link MongoDBAdapter#findOneOpts}.\n * @param {object} [opts.insertOpts] See {@link MongoDBAdapter#insertOpts}.\n * @param {object} [opts.insertManyOpts] See {@link MongoDBAdapter#insertManyOpts}.\n * @param {boolean} [opts.raw=false] See {@link Adapter#raw}.\n * @param {object} [opts.removeOpts] See {@link MongoDBAdapter#removeOpts}.\n * @param {boolean} [opts.translateId=true] See {@link MongoDBAdapter#translateId}.\n * @param {object} [opts.updateOpts] See {@link MongoDBAdapter#updateOpts}.\n * @param {string} [opts.uri=\"mongodb://localhost:27017\"] See {@link MongoDBAdapter#uri}.\n */\nexport function MongoDBAdapter (opts) {\n utils.classCallCheck(this, MongoDBAdapter)\n opts || (opts = {})\n if (utils.isString(opts)) {\n opts = { uri: opts }\n }\n utils.fillIn(opts, DEFAULTS)\n\n // Setup non-enumerable properties\n Object.defineProperties(this, {\n /**\n * A Promise that resolves to a reference to the MongoDB client being used by\n * this adapter.\n *\n * @name MongoDBAdapter#client\n * @type {Promise}\n */\n client: {\n writable: true,\n value: undefined\n },\n\n _db: {\n writable: true,\n value: undefined\n }\n })\n\n Adapter.call(this, opts)\n\n /**\n * Default options to pass to collection#count.\n *\n * @name MongoDBAdapter#countOpts\n * @type {object}\n * @default {}\n */\n this.countOpts || (this.countOpts = {})\n utils.fillIn(this.countOpts, COUNT_OPTS_DEFAULTS)\n\n /**\n * Default options to pass to collection#find.\n *\n * @name MongoDBAdapter#findOpts\n * @type {object}\n * @default {}\n */\n this.findOpts || (this.findOpts = {})\n utils.fillIn(this.findOpts, FIND_OPTS_DEFAULTS)\n\n /**\n * Default options to pass to collection#findOne.\n *\n * @name MongoDBAdapter#findOneOpts\n * @type {object}\n * @default {}\n */\n this.findOneOpts || (this.findOneOpts = {})\n utils.fillIn(this.findOneOpts, FIND_ONE_OPTS_DEFAULTS)\n\n /**\n * Default options to pass to collection#insert.\n *\n * @name MongoDBAdapter#insertOpts\n * @type {object}\n * @default {}\n */\n this.insertOpts || (this.insertOpts = {})\n utils.fillIn(this.insertOpts, INSERT_OPTS_DEFAULTS)\n\n /**\n * Default options to pass to collection#insertMany.\n *\n * @name MongoDBAdapter#insertManyOpts\n * @type {object}\n * @default {}\n */\n this.insertManyOpts || (this.insertManyOpts = {})\n utils.fillIn(this.insertManyOpts, INSERT_MANY_OPTS_DEFAULTS)\n\n /**\n * Default options to pass to collection#update.\n *\n * @name MongoDBAdapter#updateOpts\n * @type {object}\n * @default {}\n */\n this.updateOpts || (this.updateOpts = {})\n utils.fillIn(this.updateOpts, UPDATE_OPTS_DEFAULTS)\n\n /**\n * Default options to pass to collection#update.\n *\n * @name MongoDBAdapter#removeOpts\n * @type {object}\n * @default {}\n */\n this.removeOpts || (this.removeOpts = {})\n utils.fillIn(this.removeOpts, REMOVE_OPTS_DEFAULTS)\n\n this.client = new utils.Promise((resolve, reject) => {\n MongoClient.connect(opts.uri, (err, db) => {\n if (err) {\n return reject(err)\n }\n this._db = db\n resolve(db)\n })\n })\n}\n\nAdapter.extend({\n constructor: MongoDBAdapter,\n\n _translateObjectIDs (r, opts) {\n opts || (opts = {})\n if (this.getOpt('translateObjectIDs', opts)) {\n this._translateFieldObjectIDs(r)\n } else if (this.getOpt('translateId', opts)) {\n this._translateId(r)\n }\n return r\n },\n\n /**\n * Translate ObjectIDs to strings.\n *\n * @method MongoDBAdapter#_translateId\n * @return {*}\n */\n _translateId (r) {\n if (utils.isArray(r)) {\n r.forEach((_r) => {\n const __id = _r._id ? _r._id.toString() : _r._id\n _r._id = typeof __id === 'string' ? __id : _r._id\n })\n } else if (utils.isObject(r)) {\n const __id = r._id ? r._id.toString() : r._id\n r._id = typeof __id === 'string' ? __id : r._id\n }\n return r\n },\n\n _translateFieldObjectIDs (r) {\n const _checkFields = (r) => {\n for (let field in r) {\n if (r[field]._bsontype === 'ObjectID') {\n r[field] = typeof r[field].toString() === 'string' ? r[field].toString() : r[field]\n }\n }\n }\n if (utils.isArray(r)) {\n r.forEach((_r) => {\n _checkFields(_r)\n })\n } else if (utils.isObject(r)) {\n _checkFields(r)\n }\n return r\n },\n\n /**\n * Retrieve the number of records that match the selection query.\n *\n * @method MongoDBAdapter#count\n * @param {object} mapper The mapper.\n * @param {object} query Selection query.\n * @param {object} [opts] Configuration options.\n * @param {object} [opts.countOpts] Options to pass to collection#count.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * response object.\n * @param {string[]} [opts.with=[]] Relations to eager load.\n * @return {Promise}\n */\n\n /**\n * Retrieve the records that match the selection query. Internal method used\n * by Adapter#count.\n *\n * @method MongoDBAdapter#_count\n * @private\n * @param {object} mapper The mapper.\n * @param {object} query Selection query.\n * @param {object} [opts] Configuration options.\n * @return {Promise}\n */\n _count (mapper, query, opts) {\n opts || (opts = {})\n\n return this._run((client, success, failure) => {\n const collectionId = this._getCollectionId(mapper, opts)\n const countOpts = this.getOpt('countOpts', opts)\n utils.fillIn(countOpts, this.getQueryOptions(mapper, query))\n\n const mongoQuery = this.getQuery(mapper, query)\n\n client\n .collection(collectionId)\n .count(mongoQuery, countOpts, (err, count) => err ? failure(err) : success([count, {}]))\n })\n },\n\n /**\n * Create a new record.\n *\n * @method MongoDBAdapter#create\n * @param {object} mapper The mapper.\n * @param {object} props The record to be created.\n * @param {object} [opts] Configuration options.\n * @param {object} [opts.insertOpts] Options to pass to collection#insert.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * @return {Promise}\n */\n\n /**\n * Create a new record. Internal method used by Adapter#create.\n *\n * @method MongoDBAdapter#_create\n * @private\n * @param {object} mapper The mapper.\n * @param {object} props The record to be created.\n * @param {object} [opts] Configuration options.\n * @return {Promise}\n */\n _create (mapper, props, opts) {\n props || (props = {})\n opts || (opts = {})\n\n return this._run((client, success, failure) => {\n const collectionId = this._getCollectionId(mapper, opts)\n const insertOpts = this.getOpt('insertOpts', opts)\n\n const collection = client.collection(collectionId)\n const handler = (err, cursor) => err ? failure(err) : success(cursor)\n\n props = utils.plainCopy(props)\n\n if (collection.insertOne) {\n collection\n .insertOne(props, insertOpts, handler)\n } else {\n collection\n .insert(props, insertOpts, handler)\n }\n }).then((cursor) => {\n let record\n let r = cursor.ops ? cursor.ops : cursor\n this._translateObjectIDs(r, opts)\n record = utils.isArray(r) ? r[0] : r\n cursor.connection = undefined\n return [record, cursor]\n })\n },\n\n /**\n * Create multiple records in a single batch.\n *\n * @method MongoDBAdapter#createMany\n * @param {object} mapper The mapper.\n * @param {object} props The records to be created.\n * @param {object} [opts] Configuration options.\n * @param {object} [opts.insertManyOpts] Options to pass to\n * collection#insertMany.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * response object.\n * @return {Promise}\n */\n\n /**\n * Create multiple records in a single batch. Internal method used by\n * Adapter#createMany.\n *\n * @method MongoDBAdapter#_createMany\n * @private\n * @param {object} mapper The mapper.\n * @param {object} props The records to be created.\n * @param {object} [opts] Configuration options.\n * @return {Promise}\n */\n _createMany (mapper, props, opts) {\n props || (props = {})\n opts || (opts = {})\n\n return this._run((client, success, failure) => {\n const collectionId = this._getCollectionId(mapper, opts)\n const insertManyOpts = this.getOpt('insertManyOpts', opts)\n props = utils.plainCopy(props)\n\n client.collection(collectionId)\n .insertMany(props, insertManyOpts, (err, cursor) => err ? failure(err) : success(cursor))\n }).then((cursor) => {\n let records = []\n let r = cursor.ops ? cursor.ops : cursor\n this._translateObjectIDs(r, opts)\n records = r\n cursor.connection = undefined\n return [records, cursor]\n })\n },\n\n /**\n * Destroy the record with the given primary key.\n *\n * @method MongoDBAdapter#destroy\n * @param {object} mapper The mapper.\n * @param {(string|number)} id Primary key of the record to destroy.\n * @param {object} [opts] Configuration options.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * response object.\n * @param {object} [opts.removeOpts] Options to pass to collection#remove.\n * @return {Promise}\n */\n\n /**\n * Destroy the record with the given primary key. Internal method used by\n * Adapter#destroy.\n *\n * @method MongoDBAdapter#_destroy\n * @private\n * @param {object} mapper The mapper.\n * @param {(string|number)} id Primary key of the record to destroy.\n * @param {object} [opts] Configuration options.\n * @return {Promise}\n */\n _destroy (mapper, id, opts) {\n opts || (opts = {})\n\n return this._run((client, success, failure) => {\n const collectionId = this._getCollectionId(mapper, opts)\n const removeOpts = this.getOpt('removeOpts', opts)\n\n const mongoQuery = {\n [mapper.idAttribute]: this.toObjectID(mapper, id)\n }\n const collection = client.collection(collectionId)\n const handler = (err, cursor) => err ? failure(err) : success(cursor)\n\n if (collection.deleteOne) {\n collection\n .deleteOne(mongoQuery, removeOpts, handler)\n } else {\n collection\n .remove(mongoQuery, removeOpts, handler)\n }\n }).then((cursor) => [undefined, cursor])\n },\n\n /**\n * Destroy the records that match the selection query.\n *\n * @method MongoDBAdapter#destroyAll\n * @param {object} mapper the mapper.\n * @param {object} [query] Selection query.\n * @param {object} [query.where] Filtering criteria.\n * @param {string|Array} [query.orderBy] Sorting criteria.\n * @param {string|Array} [query.sort] Same as `query.sort`.\n * @param {number} [query.limit] Limit results.\n * @param {number} [query.skip] Offset results.\n * @param {number} [query.offset] Same as `query.skip`.\n * @param {object} [opts] Configuration options.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * response object.\n * @param {object} [opts.removeOpts] Options to pass to collection#remove.\n * @return {Promise}\n */\n\n /**\n * Destroy the records that match the selection query. Internal method used by\n * Adapter#destroyAll.\n *\n * @method MongoDBAdapter#_destroyAll\n * @private\n * @param {object} mapper the mapper.\n * @param {object} [query] Selection query.\n * @param {object} [opts] Configuration options.\n * @return {Promise}\n */\n _destroyAll (mapper, query, opts) {\n query || (query = {})\n opts || (opts = {})\n\n return this._run((client, success, failure) => {\n const collectionId = this._getCollectionId(mapper, opts)\n const removeOpts = this.getOpt('removeOpts', opts)\n utils.fillIn(removeOpts, this.getQueryOptions(mapper, query))\n\n const mongoQuery = this.getQuery(mapper, query)\n const collection = client.collection(collectionId)\n const handler = (err, cursor) => err ? failure(err) : success(cursor)\n\n if (collection.deleteMany) {\n collection\n .deleteMany(mongoQuery, removeOpts, handler)\n } else {\n collection\n .remove(mongoQuery, removeOpts, handler)\n }\n }).then((cursor) => {\n cursor.connection = undefined\n return [undefined, cursor]\n })\n },\n\n /**\n * Retrieve the record with the given primary key.\n *\n * @method MongoDBAdapter#find\n * @param {object} mapper The mapper.\n * @param {(string|number)} id Primary key of the record to retrieve.\n * @param {object} [opts] Configuration options.\n * @param {string|string[]|object} [opts.fields] Select a subset of fields to be returned.\n * @param {object} [opts.findOneOpts] Options to pass to collection#findOne.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * response object.\n * @param {string[]} [opts.with=[]] Relations to eager load.\n * @return {Promise}\n */\n\n /**\n * Retrieve the record with the given primary key. Internal method used by\n * Adapter#find.\n *\n * @method MongoDBAdapter#_find\n * @private\n * @param {object} mapper The mapper.\n * @param {(string|number)} id Primary key of the record to retrieve.\n * @param {object} [opts] Configuration options.\n * @param {string|string[]|object} [opts.fields] Select a subset of fields to be returned.\n * @return {Promise}\n */\n _find (mapper, id, opts) {\n opts || (opts = {})\n opts.with || (opts.with = [])\n\n return this._run((client, success, failure) => {\n const collectionId = this._getCollectionId(mapper, opts)\n const findOneOpts = this.getOpt('findOneOpts', opts)\n findOneOpts.fields = this._getFields(mapper, opts)\n\n const mongoQuery = {\n [mapper.idAttribute]: this.toObjectID(mapper, id)\n }\n\n client.collection(collectionId)\n .findOne(mongoQuery, findOneOpts, (err, record) => err ? failure(err) : success(record))\n }).then((record) => {\n if (record) {\n this._translateObjectIDs(record, opts)\n }\n return [record, {}]\n })\n },\n\n /**\n * Retrieve the records that match the selection query.\n *\n * @method MongoDBAdapter#findAll\n * @param {object} mapper The mapper.\n * @param {object} query Selection query.\n * @param {object} [opts] Configuration options.\n * @param {string|string[]|object} [opts.fields] Select a subset of fields to be returned.\n * @param {object} [opts.findOpts] Options to pass to collection#find.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * response object.\n * @param {string[]} [opts.with=[]] Relations to eager load.\n * @return {Promise}\n */\n\n /**\n * Retrieve the records that match the selection query. Internal method used\n * by Adapter#findAll.\n *\n * @method MongoDBAdapter#_findAll\n * @private\n * @param {object} mapper The mapper.\n * @param {object} query Selection query.\n * @param {object} [opts] Configuration options.\n * @param {string|string[]|object} [opts.fields] Select a subset of fields to be returned.\n * @return {Promise}\n */\n _findAll (mapper, query, opts) {\n opts || (opts = {})\n\n return this._run((client, success, failure) => {\n const collectionId = this._getCollectionId(mapper, opts)\n const findOpts = this.getOpt('findOpts', opts)\n utils.fillIn(findOpts, this.getQueryOptions(mapper, query))\n findOpts.fields = this._getFields(mapper, opts)\n\n const mongoQuery = this.getQuery(mapper, query)\n\n client.collection(collectionId)\n .find(mongoQuery, findOpts)\n .toArray((err, records) => err ? failure(err) : success(records))\n }).then((records) => {\n this._translateObjectIDs(records, opts)\n return [records, {}]\n })\n },\n\n _getCollectionId (mapper, opts) {\n opts || (opts = {})\n return opts.table || opts.collection || mapper.table || mapper.collection || underscore(mapper.name)\n },\n\n _getFields (mapper, opts) {\n opts || (opts = {})\n if (utils.isString(opts.fields)) {\n opts.fields = { [opts.fields]: 1 }\n } else if (utils.isArray(opts.fields)) {\n const fields = {}\n opts.fields.forEach((field) => {\n fields[field] = 1\n })\n return fields\n }\n return opts.fields\n },\n\n _run (cb) {\n if (this._db) {\n // Use the cached db object\n return new utils.Promise((resolve, reject) => {\n cb(this._db, resolve, reject)\n })\n }\n return this.getClient().then((client) => {\n return new utils.Promise((resolve, reject) => {\n cb(client, resolve, reject)\n })\n })\n },\n\n /**\n * Apply the given update to the record with the specified primary key.\n *\n * @method MongoDBAdapter#update\n * @param {object} mapper The mapper.\n * @param {(string|number)} id The primary key of the record to be updated.\n * @param {object} props The update to apply to the record.\n * @param {object} [opts] Configuration options.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * response object.\n * @param {object} [opts.updateOpts] Options to pass to collection#update.\n * @return {Promise}\n */\n\n /**\n * Apply the given update to the record with the specified primary key.\n * Internal method used by Adapter#update.\n *\n * @method MongoDBAdapter#_update\n * @private\n * @param {object} mapper The mapper.\n * @param {(string|number)} id The primary key of the record to be updated.\n * @param {object} props The update to apply to the record.\n * @param {object} [opts] Configuration options.\n * @return {Promise}\n */\n _update (mapper, id, props, opts) {\n props || (props = {})\n opts || (opts = {})\n\n return this._find(mapper, id, { raw: false })\n .then((result) => {\n if (!result[0]) {\n throw new Error('Not Found')\n }\n return this._run((client, success, failure) => {\n const collectionId = this._getCollectionId(mapper, opts)\n const updateOpts = this.getOpt('updateOpts', opts)\n\n const mongoQuery = {\n [mapper.idAttribute]: this.toObjectID(mapper, id)\n }\n const collection = client.collection(collectionId)\n const handler = (err, cursor) => err ? failure(err) : success(cursor)\n\n if (collection.updateOne) {\n collection\n .updateOne(mongoQuery, { $set: props }, updateOpts, handler)\n } else {\n collection\n .update(mongoQuery, { $set: props }, updateOpts, handler)\n }\n })\n })\n .then((cursor) => {\n return this._find(mapper, id, { raw: false })\n .then((result) => {\n cursor.connection = undefined\n return [result[0], cursor]\n })\n })\n },\n\n /**\n * Apply the given update to all records that match the selection query.\n *\n * @method MongoDBAdapter#updateAll\n * @param {object} mapper The mapper.\n * @param {object} props The update to apply to the selected records.\n * @param {object} [query] Selection query.\n * @param {object} [opts] Configuration options.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * response object.\n * @param {object} [opts.updateOpts] Options to pass to collection#update.\n * @return {Promise}\n */\n\n /**\n * Apply the given update to all records that match the selection query.\n * Internal method used by Adapter#updateAll.\n *\n * @method MongoDBAdapter#_updateAll\n * @private\n * @param {Object} mapper The mapper.\n * @param {Object} props The update to apply to the selected records.\n * @param {Object} [query] Selection query.\n * @param {Object} [opts] Configuration options.\n * @return {Promise}\n */\n _updateAll (mapper, props, query, opts) {\n props || (props = {})\n query || (query = {})\n opts || (opts = {})\n let ids\n\n return this._run((client, success, failure) => {\n return this._findAll(mapper, query, { raw: false }).then((result) => {\n const collectionId = this._getCollectionId(mapper, opts)\n const updateOpts = this.getOpt('updateOpts', opts)\n updateOpts.multi = true\n\n const queryOptions = this.getQueryOptions(mapper, query)\n queryOptions.$set = props\n ids = result[0].map((record) => this.toObjectID(mapper, record[mapper.idAttribute]))\n\n const mongoQuery = this.getQuery(mapper, query)\n const collection = client.collection(collectionId)\n const handler = (err, cursor) => err ? failure(err) : success(cursor)\n\n if (collection.updateMany) {\n collection\n .updateMany(mongoQuery, queryOptions, updateOpts, handler)\n } else {\n collection\n .update(mongoQuery, queryOptions, updateOpts, handler)\n }\n })\n }).then((cursor) => {\n const query = {\n [mapper.idAttribute]: {\n 'in': ids\n }\n }\n return this._findAll(mapper, query, { raw: false }).then((result) => {\n cursor.connection = undefined\n return [result[0], cursor]\n })\n })\n },\n\n /**\n * Return a Promise that resolves to a reference to the MongoDB client being\n * used by this adapter.\n *\n * Useful when you need to do anything custom with the MongoDB client library.\n *\n * @method MongoDBAdapter#getClient\n * @return {object} MongoDB client.\n */\n getClient () {\n return this.client\n },\n\n /**\n * Map filtering params in a selection query to MongoDB a filtering object.\n *\n * Handles the following:\n *\n * - where\n * - and bunch of filtering operators\n *\n * @method MongoDBAdapter#getQuery\n * @return {object}\n */\n getQuery (mapper, query) {\n query = utils.plainCopy(query || {})\n query.where || (query.where = {})\n\n utils.forOwn(query, function (config, keyword) {\n if (reserved.indexOf(keyword) === -1) {\n if (utils.isObject(config)) {\n query.where[keyword] = config\n } else {\n query.where[keyword] = {\n '==': config\n }\n }\n delete query[keyword]\n }\n })\n\n let mongoQuery = {}\n\n if (Object.keys(query.where).length !== 0) {\n utils.forOwn(query.where, function (criteria, field) {\n if (!utils.isObject(criteria)) {\n query.where[field] = {\n '==': criteria\n }\n }\n utils.forOwn(criteria, function (v, op) {\n if (op === '==' || op === '===' || op === 'contains') {\n mongoQuery[field] = v\n } else if (op === '!=' || op === '!==' || op === 'notContains') {\n mongoQuery[field] = mongoQuery[field] || {}\n mongoQuery[field].$ne = v\n } else if (op === '>') {\n mongoQuery[field] = mongoQuery[field] || {}\n mongoQuery[field].$gt = v\n } else if (op === '>=') {\n mongoQuery[field] = mongoQuery[field] || {}\n mongoQuery[field].$gte = v\n } else if (op === '<') {\n mongoQuery[field] = mongoQuery[field] || {}\n mongoQuery[field].$lt = v\n } else if (op === '<=') {\n mongoQuery[field] = mongoQuery[field] || {}\n mongoQuery[field].$lte = v\n } else if (op === 'in') {\n mongoQuery[field] = mongoQuery[field] || {}\n mongoQuery[field].$in = v\n } else if (op === 'notIn') {\n mongoQuery[field] = mongoQuery[field] || {}\n mongoQuery[field].$nin = v\n } else if (op === '|==' || op === '|===' || op === '|contains') {\n mongoQuery.$or = mongoQuery.$or || []\n let orEqQuery = {}\n orEqQuery[field] = v\n mongoQuery.$or.push(orEqQuery)\n } else if (op === '|!=' || op === '|!==' || op === '|notContains') {\n mongoQuery.$or = mongoQuery.$or || []\n let orNeQuery = {}\n orNeQuery[field] = {\n '$ne': v\n }\n mongoQuery.$or.push(orNeQuery)\n } else if (op === '|>') {\n mongoQuery.$or = mongoQuery.$or || []\n let orGtQuery = {}\n orGtQuery[field] = {\n '$gt': v\n }\n mongoQuery.$or.push(orGtQuery)\n } else if (op === '|>=') {\n mongoQuery.$or = mongoQuery.$or || []\n let orGteQuery = {}\n orGteQuery[field] = {\n '$gte': v\n }\n mongoQuery.$or.push(orGteQuery)\n } else if (op === '|<') {\n mongoQuery.$or = mongoQuery.$or || []\n let orLtQuery = {}\n orLtQuery[field] = {\n '$lt': v\n }\n mongoQuery.$or.push(orLtQuery)\n } else if (op === '|<=') {\n mongoQuery.$or = mongoQuery.$or || []\n let orLteQuery = {}\n orLteQuery[field] = {\n '$lte': v\n }\n mongoQuery.$or.push(orLteQuery)\n } else if (op === '|in') {\n mongoQuery.$or = mongoQuery.$or || []\n let orInQuery = {}\n orInQuery[field] = {\n '$in': v\n }\n mongoQuery.$or.push(orInQuery)\n } else if (op === '|notIn') {\n mongoQuery.$or = mongoQuery.$or || []\n let orNinQuery = {}\n orNinQuery[field] = {\n '$nin': v\n }\n mongoQuery.$or.push(orNinQuery)\n }\n })\n })\n }\n\n return mongoQuery\n },\n\n /**\n * Map non-filtering params in a selection query to MongoDB query options.\n *\n * Handles the following:\n *\n * - limit\n * - skip/offset\n * - orderBy/sort\n *\n * @method MongoDBAdapter#getQueryOptions\n * @return {object}\n */\n getQueryOptions (mapper, query) {\n query = utils.plainCopy(query || {})\n query.orderBy = query.orderBy || query.sort\n query.skip = query.skip || query.offset\n\n let queryOptions = {}\n\n if (query.orderBy) {\n if (utils.isString(query.orderBy)) {\n query.orderBy = [\n [query.orderBy, 'asc']\n ]\n }\n for (var i = 0; i < query.orderBy.length; i++) {\n if (utils.isString(query.orderBy[i])) {\n query.orderBy[i] = [query.orderBy[i], 'asc']\n }\n }\n queryOptions.sort = query.orderBy\n }\n\n if (query.skip) {\n queryOptions.skip = +query.skip\n }\n\n if (query.limit) {\n queryOptions.limit = +query.limit\n }\n\n return queryOptions\n },\n\n /**\n * Turn an _id into an ObjectID if it isn't already an ObjectID.\n *\n * @method MongoDBAdapter#toObjectID\n * @return {*}\n */\n toObjectID (mapper, id) {\n if (id !== undefined && mapper.idAttribute === '_id' && typeof id === 'string' && ObjectID.isValid(id) && !(id instanceof ObjectID)) {\n return new ObjectID(id)\n }\n return id\n },\n\n /**\n * Return the foreignKey from the given record for the provided relationship.\n *\n * @method MongoDBAdapter#makeBelongsToForeignKey\n * @return {*}\n */\n makeBelongsToForeignKey (mapper, def, record) {\n return this.toObjectID(def.getRelation(), Adapter.prototype.makeBelongsToForeignKey.call(this, mapper, def, record))\n },\n\n /**\n * Return the localKeys from the given record for the provided relationship.\n *\n * Override with care.\n *\n * @method MongoDBAdapter#makeHasManyLocalKeys\n * @return {*}\n */\n makeHasManyLocalKeys (mapper, def, record) {\n const relatedMapper = def.getRelation()\n const localKeys = Adapter.prototype.makeHasManyLocalKeys.call(this, mapper, def, record)\n return localKeys.map((key) => this.toObjectID(relatedMapper, key))\n },\n\n /**\n * Not supported.\n *\n * @method MongoDBAdapter#updateMany\n */\n updateMany () {\n throw new Error('not supported!')\n }\n})\n\n/**\n * Details of the current version of the `js-data-mongodb` module.\n *\n * @example\n * import {version} from 'js-data-mongodb'\n * console.log(version.full)\n *\n * @name module:js-data-mongodb.version\n * @type {object}\n * @property {string} version.full The full semver value.\n * @property {number} version.major The major version number.\n * @property {number} version.minor The minor version number.\n * @property {number} version.patch The patch version number.\n * @property {(string|boolean)} version.alpha The alpha version value,\n * otherwise `false` if the current version is not alpha.\n * @property {(string|boolean)} version.beta The beta version value,\n * otherwise `false` if the current version is not beta.\n */\nexport const version = '<%= version %>'\n\n/**\n * {@link MongoDBAdapter} class.\n *\n * @example\n * import {MongoDBAdapter} from 'js-data-mongodb'\n * const adapter = new MongoDBAdapter()\n *\n * @name module:js-data-mongodb.MongoDBAdapter\n * @see MongoDBAdapter\n * @type {Constructor}\n */\n\n/**\n * Registered as `js-data-mongodb` in NPM.\n *\n * @example Install from NPM\n * npm i --save js-data-mongodb@rc js-data@rc mongodb bson\n *\n * @example Load via CommonJS\n * var MongoDBAdapter = require('js-data-mongodb').MongoDBAdapter\n * var adapter = new MongoDBAdapter()\n *\n * @example Load via ES2015 Modules\n * import {MongoDBAdapter} from 'js-data-mongodb'\n * const adapter = new MongoDBAdapter()\n *\n * @module js-data-mongodb\n */\n\n /**\n * Create a subclass of this MongoDBAdapter:\n * @example MongoDBAdapter.extend\n * // Normally you would do: import { MongoDBAdapter } from 'js-data-mongodb'\n * const JSDataMongoDB = require('js-data-mongodb')\n * const { MongoDBAdapter } = JSDataMongoDB\n * console.log('Using JSDataMongoDB v' + JSDataMongoDB.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomMongoDBAdapterClass extends MongoDBAdapter {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customMongoDBAdapter = new CustomMongoDBAdapterClass()\n * console.log(customMongoDBAdapter.foo())\n * console.log(CustomMongoDBAdapterClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherMongoDBAdapterClass = MongoDBAdapter.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherMongoDBAdapter = new OtherMongoDBAdapterClass()\n * console.log(otherMongoDBAdapter.foo())\n * console.log(OtherMongoDBAdapterClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherMongoDBAdapterClass () {\n * MongoDBAdapter.call(this)\n * this.created_at = new Date().getTime()\n * }\n * MongoDBAdapter.extend({\n * constructor: AnotherMongoDBAdapterClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherMongoDBAdapter = new AnotherMongoDBAdapterClass()\n * console.log(anotherMongoDBAdapter.created_at)\n * console.log(anotherMongoDBAdapter.foo())\n * console.log(AnotherMongoDBAdapterClass.beep())\n *\n * @method MongoDBAdapter.extend\n * @param {object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this MongoDBAdapter class.\n * @since 3.0.0\n */\n"],"names":["utils","Adapter","reserved","ObjectID"],"mappings":"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"} \ No newline at end of file