From 37028cb0cbbd09c19a6bfe84a509019c7710e412 Mon Sep 17 00:00:00 2001 From: Jason Dobry Date: Tue, 16 Aug 2016 12:48:05 -0700 Subject: [PATCH] 1.0.0-rc.1 --- .gitignore | 2 - dist/js-data-documentdb.js | 1247 ++++++++++++++++++++++++++++++++ dist/js-data-documentdb.js.map | 1 + 3 files changed, 1248 insertions(+), 2 deletions(-) create mode 100644 dist/js-data-documentdb.js create mode 100644 dist/js-data-documentdb.js.map diff --git a/.gitignore b/.gitignore index 61d2ecc..ddb9442 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,3 @@ -dist/*.js -dist/*.map # Logs logs *.log diff --git a/dist/js-data-documentdb.js b/dist/js-data-documentdb.js new file mode 100644 index 0000000..b8a4179 --- /dev/null +++ b/dist/js-data-documentdb.js @@ -0,0 +1,1247 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +var jsData = require('js-data'); +var jsDataAdapter = require('js-data-adapter'); +var documentdb = require('documentdb'); +var underscore = _interopDefault(require('mout/string/underscore')); + +var REQUEST_OPTS_DEFAULTS = {}; +var FEED_OPTS_DEFAULTS = {}; + +var checkIfNameExists = function checkIfNameExists(name, parameters) { + var exists = false; + parameters.forEach(function (parameter) { + if (parameter.name === name) { + exists = true; + return false; + } + }); + return exists; +}; + +var addParameter = function addParameter(field, value, parameters) { + var name = '@' + field; + var newName = name; + var count = 1; + + while (checkIfNameExists(newName, parameters)) { + newName = name + count; + count++; + } + parameters.push({ + name: newName, + value: value + }); + return newName; +}; + +var equal = function equal(field, value, parameters, collectionId) { + return collectionId + '.' + field + ' = ' + addParameter(field, value, parameters); +}; + +var notEqual = function notEqual(field, value, parameters, collectionId) { + return collectionId + '.' + field + ' != ' + addParameter(field, value, parameters); +}; + +/** + * Default predicate functions for the filtering operators. These produce the + * appropriate SQL and add the necessary parameters. + * + * @name module:js-data-documentdb.OPERATORS + * @property {function} = Equality operator. + * @property {function} == Equality operator. + * @property {function} != Inequality operator. + * @property {function} > "Greater than" operator. + * @property {function} >= "Greater than or equal to" operator. + * @property {function} < "Less than" operator. + * @property {function} <= "Less than or equal to" operator. + * @property {function} in Operator to test whether a value is found in the + * provided array. + * @property {function} notIn Operator to test whether a value is NOT found in + * the provided array. + * @property {function} contains Operator to test whether an array contains the + * provided value. + * @property {function} notContains Operator to test whether an array does NOT + * contain the provided value. + */ +var OPERATORS = { + '=': equal, + '==': equal, + '===': equal, + '!=': notEqual, + '!==': notEqual, + '>': function _(field, value, parameters, collectionId) { + return collectionId + '.' + field + ' > ' + addParameter(field, value, parameters); + }, + '>=': function _(field, value, parameters, collectionId) { + return collectionId + '.' + field + ' >= ' + addParameter(field, value, parameters); + }, + '<': function _(field, value, parameters, collectionId) { + return collectionId + '.' + field + ' < ' + addParameter(field, value, parameters); + }, + '<=': function _(field, value, parameters, collectionId) { + return collectionId + '.' + field + ' <= ' + addParameter(field, value, parameters); + }, + 'in': function _in(field, value, parameters, collectionId) { + return 'ARRAY_CONTAINS(' + addParameter(field, value, parameters) + ', ' + collectionId + '.' + field + ')'; + }, + 'notIn': function notIn(field, value, parameters, collectionId) { + // return `${collectionId}.${field} NOT IN ${addParameter(field, value, parameters)}` + return 'NOT ARRAY_CONTAINS(' + addParameter(field, value, parameters) + ', ' + collectionId + '.' + field + ')'; + }, + 'contains': function contains(field, value, parameters, collectionId) { + return 'ARRAY_CONTAINS(' + collectionId + '.' + field + ', ' + addParameter(field, value, parameters) + ')'; + }, + 'notContains': function notContains(field, value, parameters, collectionId) { + return 'NOT ARRAY_CONTAINS(' + collectionId + '.' + field + ', ' + addParameter(field, value, parameters) + ')'; + } +}; + +Object.freeze(OPERATORS); + +/** + * DocumentDBAdapter class. + * + * @example + * // Use Container instead of DataStore on the server + * import { Container } from 'js-data'; + * import { DocumentDBAdapter } from 'js-data-documentdb'; + * + * // Create a store to hold your Mappers + * const store = new Container(); + * + * // Create an instance of DocumentDBAdapter with default settings + * const adapter = new DocumentDBAdapter({ + * documentOpts: { + * db: 'mydb', + * urlConnection: process.env.DOCUMENT_DB_ENDPOINT, + * auth: { + * masterKey: process.env.DOCUMENT_DB_KEY + * } + * } + * }); + * + * // Mappers in "store" will use the DocumentDB adapter by default + * store.registerAdapter('documentdb', adapter, { 'default': true }); + * + * // Create a Mapper that maps to a "user" table + * store.defineMapper('user'); + * + * @class DocumentDBAdapter + * @extends Adapter + * @param {object} [opts] Configuration options. + * @param {object} [opts.client] See {@link DocumentDBAdapter#client}. + * @param {boolean} [opts.debug=false] See {@link Adapter#debug}. + * @param {object} [opts.documentOpts={}] See {@link DocumentDBAdapter#documentOpts}. + * @param {object} [opts.feedOpts={}] See {@link DocumentDBAdapter#feedOpts}. + * @param {object} [opts.operators={@link module:js-data-documentdb.OPERATORS}] See {@link DocumentDBAdapter#operators}. + * @param {boolean} [opts.raw=false] See {@link Adapter#raw}. + * @param {object} [opts.requestOpts={}] See {@link DocumentDBAdapter#requestOpts}. + */ +function DocumentDBAdapter(opts) { + jsData.utils.classCallCheck(this, DocumentDBAdapter); + opts || (opts = {}); + + // Setup non-enumerable properties + Object.defineProperties(this, { + /** + * The DocumentDB client used by this adapter. Use this directly when you + * need to write custom queries. + * + * @example Use default instance. + * import { DocumentDBAdapter } from 'js-data-documentdb'; + * const adapter = new DocumentDBAdapter() + * adapter.client.createDatabase('foo', function (err, db) {...}); + * + * @example Configure default instance. + * import { DocumentDBAdapter } from 'js-data-documentdb'; + * const adapter = new DocumentDBAdapter({ + * documentOpts: { + * db: 'mydb', + * urlConnection: process.env.DOCUMENT_DB_ENDPOINT, + * auth: { + * masterKey: process.env.DOCUMENT_DB_KEY + * } + * } + * }); + * adapter.client.createDatabase('foo', function (err, db) {...}); + * + * @example Provide a custom instance. + * import { DocumentClient } from 'documentdb'; + * import { DocumentDBAdapter } from 'js-data-documentdb'; + * const client = new DocumentClient(...) + * const adapter = new DocumentDBAdapter({ + * client: client + * }); + * adapter.client.createDatabase('foo', function (err, db) {...}); + * + * @name DocumentDBAdapter#client + * @type {object} + */ + client: { + writable: true, + value: undefined + }, + databases: { + value: {} + }, + indices: { + value: {} + }, + collections: { + value: {} + } + }); + + jsDataAdapter.Adapter.call(this, opts); + + /** + * Default options to pass to DocumentClient requests. + * + * @name DocumentDBAdapter#requestOpts + * @type {object} + * @default {} + */ + this.requestOpts || (this.requestOpts = {}); + jsData.utils.fillIn(this.requestOpts, REQUEST_OPTS_DEFAULTS); + + /** + * Default options to pass to DocumentClient#queryDocuments. + * + * @name DocumentDBAdapter#feedOpts + * @type {object} + * @default {} + */ + this.feedOpts || (this.feedOpts = {}); + jsData.utils.fillIn(this.feedOpts, FEED_OPTS_DEFAULTS); + + /** + * Override the default predicate functions for the specified operators. + * + * @name DocumentDBAdapter#operators + * @type {object} + * @default {} + */ + this.operators || (this.operators = {}); + jsData.utils.fillIn(this.operators, OPERATORS); + + /** + * Options to pass to a new `DocumentClient` instance, if one was not provided + * at {@link DocumentDBAdapter#client}. See the [DocumentClient API][readme] + * for instance options. + * + * [readme]: http://azure.github.io/azure-documentdb-node/DocumentClient.html + * + * @name DocumentDBAdapter#documentOpts + * @see http://azure.github.io/azure-documentdb-node/DocumentClient.html + * @type {object} + * @property {string} db The default database to use. + * @property {string} urlConnection The service endpoint to use to create the + * client. + * @property {object} auth An object that is used for authenticating requests + * and must contains one of the auth options. + * @property {object} auth.masterkey The authorization master key to use to + * create the client. + * Keys for the object are resource Ids and values are the resource tokens. + * @property {object[]} auth.resourceTokens An object that contains resources tokens. + * Keys for the object are resource Ids and values are the resource tokens. + * @property {string} auth.permissionFeed An array of Permission objects. + * @property {string} [connectionPolicy] An instance of ConnectionPolicy class. + * This parameter is optional and the default connectionPolicy will be used if + * omitted. + * @property {string} [consistencyLevel] An optional parameter that represents + * the consistency level. It can take any value from ConsistencyLevel. + */ + this.documentOpts || (this.documentOpts = {}); + + if (!this.client) { + this.client = new documentdb.DocumentClient(this.documentOpts.urlConnection, this.documentOpts.auth, this.documentOpts.connectionPolicy, this.documentOpts.consistencyLevel); + } +} + +jsDataAdapter.Adapter.extend({ + constructor: DocumentDBAdapter, + + _count: function _count(mapper, query, opts) { + opts || (opts = {}); + query || (query = {}); + + var collectionId = mapper.collection || underscore(mapper.name); + opts.select = collectionId + '.' + mapper.idAttribute; + + return this._findAll(mapper, query, opts).then(function (result) { + return [result[0].length, { found: result[0].length }]; + }); + }, + _create: function _create(mapper, props, opts) { + var _this = this; + + props || (props = {}); + opts || (opts = {}); + + return new jsData.utils.Promise(function (resolve, reject) { + _this.client.createDocument(_this.getCollectionLink(mapper, opts), jsData.utils.plainCopy(props), _this.getOpt('requestOpts', opts), function (err, document) { + if (err) { + return reject(err); + } + return resolve([document, { created: 1 }]); + }); + }); + }, + _createMany: function _createMany(mapper, props, opts) { + var _this2 = this; + + props || (props = {}); + opts || (opts = {}); + + return jsData.utils.Promise.all(props.map(function (record) { + return _this2._create(mapper, record, opts); + })).then(function (results) { + return results.map(function (result) { + return result[0]; + }); + }).then(function (results) { + return [results, { created: results.length }]; + }); + }, + _destroy: function _destroy(mapper, id, opts) { + var _this3 = this; + + opts || (opts = {}); + + var collLink = this.getCollectionLink(mapper, opts); + var requestOpts = this.getOpt('requestOpts', opts); + + return new jsData.utils.Promise(function (resolve, reject) { + _this3.client.deleteDocument(collLink + '/docs/' + id, requestOpts, function (err) { + if (err) { + if (err.code === 404) { + return resolve([undefined, { deleted: 0 }]); + } + return reject(err); + } + return resolve([undefined, { deleted: 1 }]); + }); + }); + }, + _destroyAll: function _destroyAll(mapper, query, opts) { + var _this4 = this; + + query || (query = {}); + opts || (opts = {}); + + var destroyFn = function destroyFn(document) { + return _this4._destroy(mapper, document.id, opts); + }; + + return this._findAll(mapper, query, opts).then(function (results) { + return jsData.utils.Promise.all(results[0].map(destroyFn)); + }).then(function (results) { + return [undefined, { deleted: results.length }]; + }); + }, + _find: function _find(mapper, id, opts) { + var _this5 = this; + + opts || (opts = {}); + + var docLink = this.getCollectionLink(mapper, opts) + '/docs/' + id; + var requestOpts = this.getOpt('requestOpts', opts); + + return new jsData.utils.Promise(function (resolve, reject) { + _this5.client.readDocument(docLink, requestOpts, function (err, document) { + if (err) { + if (err.code === 404) { + return resolve([undefined, { found: 0 }]); + } + return reject(err); + } + return resolve([document, { found: document ? 1 : 0 }]); + }); + }); + }, + _findAll: function _findAll(mapper, query, opts) { + var _this6 = this; + + opts || (opts = {}); + query || (query = {}); + + var collLink = this.getCollectionLink(mapper, opts); + var feedOpts = this.getOpt('feedOpts', opts); + var querySpec = this.getQuerySpec(mapper, query, opts); + + return new jsData.utils.Promise(function (resolve, reject) { + _this6.client.queryDocuments(collLink, querySpec, feedOpts).toArray(function (err, documents) { + if (err) { + return reject(err); + } + return resolve([documents, { found: documents.length }]); + }); + }); + }, + _sum: function _sum(mapper, field, query, opts) { + if (!jsData.utils.isString(field)) { + throw new Error('field must be a string!'); + } + opts || (opts = {}); + query || (query = {}); + + var collectionId = mapper.collection || underscore(mapper.name); + opts.select = collectionId + '.' + mapper.idAttribute + ', ' + collectionId + '.' + field; + + return this._findAll(mapper, query, opts).then(function (result) { + var sum = result[0].reduce(function (sum, cur) { + return sum + cur[field]; + }, 0); + return [sum, { found: result[0].length }]; + }); + }, + _update: function _update(mapper, id, props, opts) { + var _this7 = this; + + props || (props = {}); + opts || (opts = {}); + + var docLink = this.getCollectionLink(mapper, opts) + '/docs/' + id; + var requestOpts = this.getOpt('requestOpts', opts); + + return this._find(mapper, id, opts).then(function (result) { + var document = result[0]; + if (!document) { + throw new Error('Not Found'); + } + jsData.utils.deepMixIn(document, jsData.utils.plainCopy(props)); + return new jsData.utils.Promise(function (resolve, reject) { + _this7.client.replaceDocument(docLink, document, requestOpts, function (err, updatedDocument) { + if (err) { + return reject(err); + } + return resolve([updatedDocument, { updated: updatedDocument ? 1 : 0 }]); + }); + }); + }); + }, + _updateAll: function _updateAll(mapper, props, query, opts) { + var _this8 = this; + + props || (props = {}); + query || (query = {}); + opts || (opts = {}); + + props = jsData.utils.plainCopy(props); + + var requestOpts = this.getOpt('requestOpts', opts); + var collLink = this.getCollectionLink(mapper, opts); + + return this._findAll(mapper, query, opts).then(function (result) { + var documents = result[0]; + documents.forEach(function (document) { + jsData.utils.deepMixIn(document, props); + }); + return jsData.utils.Promise.all(documents.map(function (document) { + return new jsData.utils.Promise(function (resolve, reject) { + var docLink = collLink + '/docs/' + document.id; + _this8.client.replaceDocument(docLink, document, requestOpts, function (err, updatedDocument) { + if (err) { + return reject(err); + } + return resolve(updatedDocument); + }); + }); + })); + }).then(function (documents) { + return [documents, { updated: documents.length }]; + }); + }, + _updateMany: function _updateMany(mapper, records, opts) { + var _this9 = this; + + records || (records = []); + opts || (opts = {}); + + records = records.filter(function (record) { + return record && record.id !== undefined; + }); + + return jsData.utils.Promise.all(records.map(function (record) { + return _this9._update(mapper, record.id, record, opts); + })).then(function (results) { + return [results.map(function (result) { + return result[0]; + }), { updated: results.length }]; + }); + }, + _applyWhereFromObject: function _applyWhereFromObject(where) { + var fields = []; + var ops = []; + var predicates = []; + jsData.utils.forOwn(where, function (clause, field) { + if (!jsData.utils.isObject(clause)) { + clause = { + '==': clause + }; + } + jsData.utils.forOwn(clause, function (expr, op) { + fields.push(field); + ops.push(op); + predicates.push(expr); + }); + }); + return { + fields: fields, + ops: ops, + predicates: predicates + }; + }, + _applyWhereFromArray: function _applyWhereFromArray(where) { + var _this10 = this; + + var groups = []; + where.forEach(function (_where, i) { + if (jsData.utils.isString(_where)) { + return; + } + var prev = where[i - 1]; + var parser = jsData.utils.isArray(_where) ? _this10._applyWhereFromArray : _this10._applyWhereFromObject; + var group = parser.call(_this10, _where); + if (prev === 'or') { + group.isOr = true; + } + groups.push(group); + }); + groups.isArray = true; + return groups; + }, + _testObjectGroup: function _testObjectGroup(sql, group, parameters, collectionId, opts) { + var i = void 0; + var fields = group.fields; + var ops = group.ops; + var predicates = group.predicates; + var len = ops.length; + for (i = 0; i < len; i++) { + var op = ops[i]; + var isOr = op.charAt(0) === '|'; + op = isOr ? op.substr(1) : op; + var predicateFn = this.getOperator(op, opts); + if (predicateFn) { + var subSql = predicateFn(fields[i], predicates[i], parameters, collectionId); + if (isOr) { + sql = sql ? sql + ' OR (' + subSql + ')' : '(' + subSql + ')'; + } else { + sql = sql ? sql + ' AND (' + subSql + ')' : '(' + subSql + ')'; + } + } else { + throw new Error('Operator ' + op + ' not supported!'); + } + } + return sql; + }, + _testArrayGroup: function _testArrayGroup(sql, groups, parameters, collectionId, opts) { + var i = void 0; + var len = groups.length; + for (i = 0; i < len; i++) { + var group = groups[i]; + var subQuery = void 0; + if (group.isArray) { + subQuery = this._testArrayGroup(sql, group, parameters, collectionId, opts); + } else { + subQuery = this._testObjectGroup(null, group, parameters, collectionId, opts); + } + if (groups[i - 1]) { + if (group.isOr) { + sql += ' OR (' + subQuery + ')'; + } else { + sql += ' AND (' + subQuery + ')'; + } + } else { + sql = sql ? sql + (' AND (' + subQuery + ')') : '(' + subQuery + ')'; + } + } + return sql; + }, + + + /** + * Generate the querySpec object for DocumentClient#queryDocuments. + * + * @name DocumentDBAdapter#getQuerySpec + * @method + * @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.operators] Override the default predicate functions + * for specified operators. + */ + getQuerySpec: function getQuerySpec(mapper, query, opts) { + query = jsData.utils.plainCopy(query || {}); + opts || (opts = {}); + opts.operators || (opts.operators = {}); + query.where || (query.where = {}); + query.orderBy || (query.orderBy = query.sort); + query.orderBy || (query.orderBy = []); + query.skip || (query.skip = query.offset); + var collectionId = mapper.collection || underscore(mapper.name); + + var select = opts.select || '*'; + var sql = select + ' FROM ' + collectionId; + var whereSql = void 0; + var parameters = []; + + // Transform non-keyword properties to "where" clause configuration + jsData.utils.forOwn(query, function (config, keyword) { + if (jsDataAdapter.reserved.indexOf(keyword) === -1 && jsData.utils.isObject(query.where)) { + if (jsData.utils.isObject(config)) { + query.where[keyword] = config; + } else { + query.where[keyword] = { + '==': config + }; + } + delete query[keyword]; + } + }); + + // Filter + var groups = void 0; + + if (jsData.utils.isObject(query.where) && Object.keys(query.where).length !== 0) { + groups = this._applyWhereFromArray([query.where]); + } else if (jsData.utils.isArray(query.where)) { + groups = this._applyWhereFromArray(query.where); + } + + if (groups) { + whereSql = this._testArrayGroup(null, groups, parameters, collectionId, opts); + } + + if (whereSql) { + sql = sql + ' WHERE ' + whereSql; + } + + // Sort + var orderBySql = ''; + if (query.orderBy) { + if (jsData.utils.isString(query.orderBy)) { + query.orderBy = [[query.orderBy, 'asc']]; + } + for (var i = 0; i < query.orderBy.length; i++) { + if (jsData.utils.isString(query.orderBy[i])) { + query.orderBy[i] = [query.orderBy[i], 'asc']; + } + var subOrderBySql = (query.orderBy[i][1] || '').toUpperCase() === 'DESC' ? collectionId + '.' + query.orderBy[i][0] + ' DESC' : collectionId + '.' + query.orderBy[i][0]; + if (orderBySql) { + orderBySql = orderBySql + ', ' + subOrderBySql; + } else { + orderBySql = subOrderBySql; + } + } + if (orderBySql) { + orderBySql = 'ORDER BY ' + orderBySql; + } + } + + // Offset + // if (query.skip) { + // sql += ` SKIP ${+query.skip}` + // } + + // Limit + if (query.limit) { + sql = 'TOP ' + +query.limit + ' ' + sql; + } + + sql = 'SELECT ' + sql + (orderBySql ? ' ' + orderBySql : ''); + return { + query: sql, + parameters: parameters + }; + }, + getDbLink: function getDbLink(opts) { + return 'dbs/' + (opts.db === undefined ? this.documentOpts.db : opts.db); + }, + getCollectionLink: function getCollectionLink(mapper, opts) { + return this.getDbLink(opts) + '/colls/' + (mapper.collection || underscore(mapper.name)); + }, + waitForDb: function waitForDb(opts) { + var _this11 = this; + + opts || (opts = {}); + var dbId = jsData.utils.isUndefined(opts.db) ? this.documentOpts.db : opts.db; + if (!this.databases[dbId]) { + this.databases[dbId] = new jsData.utils.Promise(function (resolve, reject) { + _this11.client.readDatabases().toArray(function (err, dbs) { + if (err) { + return reject(err); + } + var existing = void 0; + dbs.forEach(function (db) { + if (dbId === db.id) { + existing = db; + return false; + } + }); + if (!existing) { + return _this11.client.createDatabase({ id: dbId }, function (err, db) { + if (err) { + return reject(err); + } + return resolve(db); + }); + } + return resolve(existing); + }); + }); + } + return this.databases[dbId]; + }, + waitForCollection: function waitForCollection(mapper, opts) { + var _this12 = this; + + opts || (opts = {}); + var collectionId = jsData.utils.isString(mapper) ? mapper : mapper.collection || underscore(mapper.name); + var dbId = jsData.utils.isUndefined(opts.db) ? this.documentOpts.db : opts.db; + return this.waitForDb(opts).then(function () { + _this12.collections[dbId] = _this12.collections[dbId] || {}; + if (!_this12.collections[dbId][collectionId]) { + _this12.collections[dbId][collectionId] = new jsData.utils.Promise(function (resolve, reject) { + _this12.client.readCollections('dbs/' + dbId).toArray(function (err, collections) { + if (err) { + return reject(err); + } + var existing = void 0; + collections.forEach(function (collection) { + if (collectionId === collection.id) { + existing = collection; + return false; + } + }); + if (!existing) { + return _this12.client.createCollection('dbs/' + dbId, { id: collectionId }, function (err, collection) { + if (err) { + return reject(err); + } + return resolve(collection); + }); + } + return resolve(existing); + }); + }); + } + return _this12.collections[dbId][collectionId]; + }); + }, + + + /** + * Return the number of records that match the selection query. + * + * @name DocumentDBAdapter#count + * @method + * @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.operators] Override the default predicate functions + * for specified operators. + * @param {boolean} [opts.raw=false] Whether to return a more detailed + * response object. + * @param {object} [opts.requestOpts] Options to pass to the DocumentClient request. + * @return {Promise} + */ + count: function count(mapper, query, opts) { + var _this13 = this; + + opts || (opts = {}); + query || (query = {}); + + return this.waitForCollection(mapper, opts).then(function () { + return jsDataAdapter.Adapter.prototype.count.call(_this13, mapper, query, opts); + }); + }, + + + /** + * Create a new record. + * + * @name DocumentDBAdapter#create + * @method + * @param {object} mapper The mapper. + * @param {object} props The record to be created. + * @param {object} [opts] Configuration options. + * @param {boolean} [opts.raw=false] Whether to return a more detailed + * response object. + * @param {object} [opts.requestOpts] Options to pass to the DocumentClient request. + * @return {Promise} + */ + create: function create(mapper, props, opts) { + var _this14 = this; + + props || (props = {}); + opts || (opts = {}); + + return this.waitForCollection(mapper, opts).then(function () { + return jsDataAdapter.Adapter.prototype.create.call(_this14, mapper, props, opts); + }); + }, + + + /** + * Create multiple records in a single batch. + * + * @name DocumentDBAdapter#createMany + * @method + * @param {object} mapper The mapper. + * @param {object} props The records to be created. + * @param {object} [opts] Configuration options. + * @param {boolean} [opts.raw=false] Whether to return a more detailed + * response object. + * @param {object} [opts.requestOpts] Options to pass to the DocumentClient request. + * @return {Promise} + */ + createMany: function createMany(mapper, props, opts) { + var _this15 = this; + + props || (props = {}); + opts || (opts = {}); + + return this.waitForCollection(mapper, opts).then(function () { + return jsDataAdapter.Adapter.prototype.createMany.call(_this15, mapper, props, opts); + }); + }, + + + /** + * Destroy the record with the given primary key. + * + * @name DocumentDBAdapter#destroy + * @method + * @param {object} mapper The mapper. + * @param {(string|number)} id Primary key of the record to destroy. + * @param {object} [opts] Configuration options. + * @param {boolean} [opts.raw=false] Whether to return a more detailed + * response object. + * @param {object} [opts.requestOpts] Options to pass to the DocumentClient request. + * @return {Promise} + */ + destroy: function destroy(mapper, id, opts) { + var _this16 = this; + + opts || (opts = {}); + + return this.waitForCollection(mapper, opts).then(function () { + return jsDataAdapter.Adapter.prototype.destroy.call(_this16, mapper, id, opts); + }); + }, + + + /** + * Destroy the records that match the selection query. + * + * @name DocumentDBAdapter#destroyAll + * @method + * @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.feedOpts] Options to pass to the DocumentClient#queryDocuments. + * @param {object} [opts.operators] Override the default predicate functions + * for specified operators. + * @param {boolean} [opts.raw=false] Whether to return a more detailed + * response object. + * @param {object} [opts.requestOpts] Options to pass to the DocumentClient request. + * @return {Promise} + */ + destroyAll: function destroyAll(mapper, query, opts) { + var _this17 = this; + + opts || (opts = {}); + query || (query = {}); + + return this.waitForCollection(mapper, opts).then(function () { + return jsDataAdapter.Adapter.prototype.destroyAll.call(_this17, mapper, query, opts); + }); + }, + + + /** + * Retrieve the record with the given primary key. + * + * @name DocumentDBAdapter#find + * @method + * @param {object} mapper The mapper. + * @param {(string|number)} id Primary key of the record to retrieve. + * @param {object} [opts] Configuration options. + * @param {boolean} [opts.raw=false] Whether to return a more detailed + * response object. + * @param {object} [opts.requestOpts] Options to pass to the DocumentClient request. + * @param {string[]} [opts.with=[]] Relations to eager load. + * @return {Promise} + */ + find: function find(mapper, id, opts) { + var _this18 = this; + + opts || (opts = {}); + + return this.waitForCollection(mapper, opts).then(function () { + return jsDataAdapter.Adapter.prototype.find.call(_this18, mapper, id, opts); + }); + }, + + + /** + * Retrieve the records that match the selection query. + * + * @name DocumentDBAdapter#findAll + * @method + * @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.feedOpts] Options to pass to the DocumentClient#queryDocuments. + * @param {object} [opts.operators] Override the default predicate functions + * for specified operators. + * @param {boolean} [opts.raw=false] Whether to return a more detailed + * response object. + * @param {object} [opts.requestOpts] Options to pass to the DocumentClient request. + * @param {string[]} [opts.with=[]] Relations to eager load. + * @return {Promise} + */ + findAll: function findAll(mapper, query, opts) { + var _this19 = this; + + opts || (opts = {}); + query || (query = {}); + + return this.waitForCollection(mapper, opts).then(function () { + return jsDataAdapter.Adapter.prototype.findAll.call(_this19, mapper, query, opts); + }); + }, + + + /** + * Resolve the predicate function for the specified operator based on the + * given options and this adapter's settings. + * + * @name DocumentDBAdapter#getOperator + * @method + * @param {string} operator The name of the operator. + * @param {object} [opts] Configuration options. + * @param {object} [opts.operators] Override the default predicate functions + * for specified operators. + * @return {*} The predicate function for the specified operator. + */ + getOperator: function getOperator(operator, opts) { + opts || (opts = {}); + opts.operators || (opts.operators = {}); + var ownOps = this.operators || {}; + return jsData.utils.isUndefined(opts.operators[operator]) ? ownOps[operator] : opts.operators[operator]; + }, + + + /** + * Return the sum of the specified field of records that match the selection + * query. + * + * @name DocumentDBAdapter#sum + * @method + * @param {object} mapper The mapper. + * @param {string} field The field to sum. + * @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.feedOpts] Options to pass to the DocumentClient#queryDocuments. + * @param {object} [opts.operators] Override the default predicate functions + * for specified operators. + * @param {boolean} [opts.raw=false] Whether to return a more detailed + * response object. + * @param {object} [opts.requestOpts] Options to pass to the DocumentClient request. + * @return {Promise} + */ + sum: function sum(mapper, field, query, opts) { + var _this20 = this; + + opts || (opts = {}); + query || (query = {}); + + return this.waitForCollection(mapper, opts).then(function () { + return jsDataAdapter.Adapter.prototype.sum.call(_this20, mapper, field, query, opts); + }); + }, + + + /** + * Apply the given update to the record with the specified primary key. + * + * @name DocumentDBAdapter#update + * @method + * @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 {boolean} [opts.raw=false] Whether to return a more detailed + * response object. + * @param {object} [opts.requestOpts] Options to pass to the DocumentClient request. + * @return {Promise} + */ + update: function update(mapper, id, props, opts) { + var _this21 = this; + + props || (props = {}); + opts || (opts = {}); + + return this.waitForCollection(mapper, opts).then(function () { + return jsDataAdapter.Adapter.prototype.update.call(_this21, mapper, id, props, opts); + }); + }, + + + /** + * Apply the given update to all records that match the selection query. + * + * @name DocumentDBAdapter#updateAll + * @method + * @param {object} mapper The mapper. + * @param {object} props The update to apply to the selected records. + * @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.feedOpts] Options to pass to the DocumentClient#queryDocuments. + * @param {object} [opts.operators] Override the default predicate functions + * for specified operators. + * @param {boolean} [opts.raw=false] Whether to return a more detailed + * response object. + * @param {object} [opts.requestOpts] Options to pass to the DocumentClient request. + * @return {Promise} + */ + updateAll: function updateAll(mapper, props, query, opts) { + var _this22 = this; + + props || (props = {}); + query || (query = {}); + opts || (opts = {}); + + return this.waitForCollection(mapper, opts).then(function () { + return jsDataAdapter.Adapter.prototype.updateAll.call(_this22, mapper, props, query, opts); + }); + }, + + + /** + * Update the given records in a single batch. + * + * @name DocumentDBAdapter#updateMany + * @method + * @param {object} mapper The mapper. + * @param {Object[]} records The records to update. + * @param {object} [opts] Configuration options. + * @param {boolean} [opts.raw=false] Whether to return a more detailed + * response object. + * @param {object} [opts.requestOpts] Options to pass to the DocumentClient request. + * @return {Promise} + */ + updateMany: function updateMany(mapper, records, opts) { + var _this23 = this; + + records || (records = []); + opts || (opts = {}); + + return this.waitForCollection(mapper, opts).then(function () { + return jsDataAdapter.Adapter.prototype.updateMany.call(_this23, mapper, records, opts); + }); + } +}); + +/** + * Details of the current version of the `js-data-documentdb` module. + * + * @example ES2015 modules import + * import {version} from 'js-data-documentdb' + * console.log(version.full) + * + * @example CommonJS import + * var version = require('js-data-documentdb').version + * console.log(version.full) + * + * @name module:js-data-documentdb.version + * @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. + * @property {number} version.patch The patch version number. + * @property {(string|boolean)} version.alpha The alpha version value, + * otherwise `false` if the current version is not alpha. + * @property {(string|boolean)} version.beta The beta version value, + * otherwise `false` if the current version is not beta. + */ +var version = { + full: '1.0.0-rc.1', + major: 1, + minor: 0, + patch: 0 +}; + +/** + * {@link DocumentDBAdapter} class. + * + * @example ES2015 modules import + * import {DocumentDBAdapter} from 'js-data-documentdb' + * const adapter = new DocumentDBAdapter() + * + * @example CommonJS import + * var DocumentDBAdapter = require('js-data-documentdb').DocumentDBAdapter + * var adapter = new DocumentDBAdapter() + * + * @name module:js-data-documentdb.DocumentDBAdapter + * @see DocumentDBAdapter + * @type {Constructor} + */ + +/** + * Registered as `js-data-documentdb` in NPM. + * + * @example Install from NPM + * npm i --save js-data-documentdb js-data documentdb + * + * @example ES2015 modules import + * import { DocumentDBAdapter } from 'js-data-documentdb' + * const adapter = new DocumentDBAdapter({ + * documentOpts: { + * db: 'mydb', + * urlConnection: process.env.DOCUMENT_DB_ENDPOINT, + * auth: { + * masterKey: process.env.DOCUMENT_DB_KEY + * } + * } + * }) + * + * @example CommonJS import + * var DocumentDBAdapter = require('js-data-documentdb').DocumentDBAdapter + * var adapter = new DocumentDBAdapter({ + * documentOpts: { + * db: 'mydb', + * urlConnection: process.env.DOCUMENT_DB_ENDPOINT, + * auth: { + * masterKey: process.env.DOCUMENT_DB_KEY + * } + * } + * }) + * + * @module js-data-documentdb + */ + +/** + * Create a subclass of this DocumentDBAdapter: + * @example DocumentDBAdapter.extend + * // Normally you would do: import {DocumentDBAdapter} from 'js-data-documentdb' + * const JSDataDocumentDB = require('js-data-documentdb') + * const { DocumentDBAdapter } = JSDataDocumentDB + * console.log('Using JSDataDocumentDB v' + JSDataDocumentDB.version.full) + * + * // Extend the class using ES2015 class syntax. + * class CustomDocumentDBAdapterClass extends DocumentDBAdapter { + * foo () { return 'bar' } + * static beep () { return 'boop' } + * } + * const customDocumentDBAdapter = new CustomDocumentDBAdapterClass({ + * documentOpts: { + * db: 'mydb', + * urlConnection: process.env.DOCUMENT_DB_ENDPOINT, + * auth: { + * masterKey: process.env.DOCUMENT_DB_KEY + * } + * } + * }) + * console.log(customDocumentDBAdapter.foo()) + * console.log(CustomDocumentDBAdapterClass.beep()) + * + * // Extend the class using alternate method. + * const OtherDocumentDBAdapterClass = DocumentDBAdapter.extend({ + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const otherDocumentDBAdapter = new OtherDocumentDBAdapterClass({ + * documentOpts: { + * db: 'mydb', + * urlConnection: process.env.DOCUMENT_DB_ENDPOINT, + * auth: { + * masterKey: process.env.DOCUMENT_DB_KEY + * } + * } + * }) + * console.log(otherDocumentDBAdapter.foo()) + * console.log(OtherDocumentDBAdapterClass.beep()) + * + * // Extend the class, providing a custom constructor. + * function AnotherDocumentDBAdapterClass () { + * DocumentDBAdapter.call(this) + * this.created_at = new Date().getTime() + * } + * DocumentDBAdapter.extend({ + * constructor: AnotherDocumentDBAdapterClass, + * foo () { return 'bar' } + * }, { + * beep () { return 'boop' } + * }) + * const anotherDocumentDBAdapter = new AnotherDocumentDBAdapterClass({ + * documentOpts: { + * db: 'mydb', + * urlConnection: process.env.DOCUMENT_DB_ENDPOINT, + * auth: { + * masterKey: process.env.DOCUMENT_DB_KEY + * } + * } + * }) + * console.log(anotherDocumentDBAdapter.created_at) + * console.log(anotherDocumentDBAdapter.foo()) + * console.log(AnotherDocumentDBAdapterClass.beep()) + * + * @method DocumentDBAdapter.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 DocumentDBAdapter class. + * @since 3.0.0 + */ + +exports.OPERATORS = OPERATORS; +exports.DocumentDBAdapter = DocumentDBAdapter; +exports.version = version; +//# sourceMappingURL=js-data-documentdb.js.map diff --git a/dist/js-data-documentdb.js.map b/dist/js-data-documentdb.js.map new file mode 100644 index 0000000..715ecb1 --- /dev/null +++ b/dist/js-data-documentdb.js.map @@ -0,0 +1 @@ +{"version":3,"file":null,"sources":["../src/index.js"],"sourcesContent":["import {utils} from 'js-data'\nimport {\n Adapter,\n reserved\n} from 'js-data-adapter'\nimport {DocumentClient} from 'documentdb'\nimport underscore from 'mout/string/underscore'\n\nconst REQUEST_OPTS_DEFAULTS = {}\nconst FEED_OPTS_DEFAULTS = {}\n\nconst checkIfNameExists = function (name, parameters) {\n let exists = false\n parameters.forEach(function (parameter) {\n if (parameter.name === name) {\n exists = true\n return false\n }\n })\n return exists\n}\n\nconst addParameter = function (field, value, parameters) {\n const name = `@${field}`\n let newName = name\n let count = 1\n\n while (checkIfNameExists(newName, parameters)) {\n newName = name + count\n count++\n }\n parameters.push({\n name: newName,\n value\n })\n return newName\n}\n\nconst equal = function (field, value, parameters, collectionId) {\n return `${collectionId}.${field} = ${addParameter(field, value, parameters)}`\n}\n\nconst notEqual = function (field, value, parameters, collectionId) {\n return `${collectionId}.${field} != ${addParameter(field, value, parameters)}`\n}\n\n/**\n * Default predicate functions for the filtering operators. These produce the\n * appropriate SQL and add the necessary parameters.\n *\n * @name module:js-data-documentdb.OPERATORS\n * @property {function} = Equality operator.\n * @property {function} == Equality operator.\n * @property {function} != Inequality operator.\n * @property {function} > \"Greater than\" operator.\n * @property {function} >= \"Greater than or equal to\" operator.\n * @property {function} < \"Less than\" operator.\n * @property {function} <= \"Less than or equal to\" operator.\n * @property {function} in Operator to test whether a value is found in the\n * provided array.\n * @property {function} notIn Operator to test whether a value is NOT found in\n * the provided array.\n * @property {function} contains Operator to test whether an array contains the\n * provided value.\n * @property {function} notContains Operator to test whether an array does NOT\n * contain the provided value.\n */\nexport const OPERATORS = {\n '=': equal,\n '==': equal,\n '===': equal,\n '!=': notEqual,\n '!==': notEqual,\n '>': function (field, value, parameters, collectionId) {\n return `${collectionId}.${field} > ${addParameter(field, value, parameters)}`\n },\n '>=': function (field, value, parameters, collectionId) {\n return `${collectionId}.${field} >= ${addParameter(field, value, parameters)}`\n },\n '<': function (field, value, parameters, collectionId) {\n return `${collectionId}.${field} < ${addParameter(field, value, parameters)}`\n },\n '<=': function (field, value, parameters, collectionId) {\n return `${collectionId}.${field} <= ${addParameter(field, value, parameters)}`\n },\n 'in': function (field, value, parameters, collectionId) {\n return `ARRAY_CONTAINS(${addParameter(field, value, parameters)}, ${collectionId}.${field})`\n },\n 'notIn': function (field, value, parameters, collectionId) {\n // return `${collectionId}.${field} NOT IN ${addParameter(field, value, parameters)}`\n return `NOT ARRAY_CONTAINS(${addParameter(field, value, parameters)}, ${collectionId}.${field})`\n },\n 'contains': function (field, value, parameters, collectionId) {\n return `ARRAY_CONTAINS(${collectionId}.${field}, ${addParameter(field, value, parameters)})`\n },\n 'notContains': function (field, value, parameters, collectionId) {\n return `NOT ARRAY_CONTAINS(${collectionId}.${field}, ${addParameter(field, value, parameters)})`\n }\n}\n\nObject.freeze(OPERATORS)\n\n/**\n * DocumentDBAdapter class.\n *\n * @example\n * // Use Container instead of DataStore on the server\n * import { Container } from 'js-data';\n * import { DocumentDBAdapter } from 'js-data-documentdb';\n *\n * // Create a store to hold your Mappers\n * const store = new Container();\n *\n * // Create an instance of DocumentDBAdapter with default settings\n * const adapter = new DocumentDBAdapter({\n * documentOpts: {\n * db: 'mydb',\n * urlConnection: process.env.DOCUMENT_DB_ENDPOINT,\n * auth: {\n * masterKey: process.env.DOCUMENT_DB_KEY\n * }\n * }\n * });\n *\n * // Mappers in \"store\" will use the DocumentDB adapter by default\n * store.registerAdapter('documentdb', adapter, { 'default': true });\n *\n * // Create a Mapper that maps to a \"user\" table\n * store.defineMapper('user');\n *\n * @class DocumentDBAdapter\n * @extends Adapter\n * @param {object} [opts] Configuration options.\n * @param {object} [opts.client] See {@link DocumentDBAdapter#client}.\n * @param {boolean} [opts.debug=false] See {@link Adapter#debug}.\n * @param {object} [opts.documentOpts={}] See {@link DocumentDBAdapter#documentOpts}.\n * @param {object} [opts.feedOpts={}] See {@link DocumentDBAdapter#feedOpts}.\n * @param {object} [opts.operators={@link module:js-data-documentdb.OPERATORS}] See {@link DocumentDBAdapter#operators}.\n * @param {boolean} [opts.raw=false] See {@link Adapter#raw}.\n * @param {object} [opts.requestOpts={}] See {@link DocumentDBAdapter#requestOpts}.\n */\nexport function DocumentDBAdapter (opts) {\n utils.classCallCheck(this, DocumentDBAdapter)\n opts || (opts = {})\n\n // Setup non-enumerable properties\n Object.defineProperties(this, {\n /**\n * The DocumentDB client used by this adapter. Use this directly when you\n * need to write custom queries.\n *\n * @example Use default instance.\n * import { DocumentDBAdapter } from 'js-data-documentdb';\n * const adapter = new DocumentDBAdapter()\n * adapter.client.createDatabase('foo', function (err, db) {...});\n *\n * @example Configure default instance.\n * import { DocumentDBAdapter } from 'js-data-documentdb';\n * const adapter = new DocumentDBAdapter({\n * documentOpts: {\n * db: 'mydb',\n * urlConnection: process.env.DOCUMENT_DB_ENDPOINT,\n * auth: {\n * masterKey: process.env.DOCUMENT_DB_KEY\n * }\n * }\n * });\n * adapter.client.createDatabase('foo', function (err, db) {...});\n *\n * @example Provide a custom instance.\n * import { DocumentClient } from 'documentdb';\n * import { DocumentDBAdapter } from 'js-data-documentdb';\n * const client = new DocumentClient(...)\n * const adapter = new DocumentDBAdapter({\n * client: client\n * });\n * adapter.client.createDatabase('foo', function (err, db) {...});\n *\n * @name DocumentDBAdapter#client\n * @type {object}\n */\n client: {\n writable: true,\n value: undefined\n },\n databases: {\n value: {}\n },\n indices: {\n value: {}\n },\n collections: {\n value: {}\n }\n })\n\n Adapter.call(this, opts)\n\n /**\n * Default options to pass to DocumentClient requests.\n *\n * @name DocumentDBAdapter#requestOpts\n * @type {object}\n * @default {}\n */\n this.requestOpts || (this.requestOpts = {})\n utils.fillIn(this.requestOpts, REQUEST_OPTS_DEFAULTS)\n\n /**\n * Default options to pass to DocumentClient#queryDocuments.\n *\n * @name DocumentDBAdapter#feedOpts\n * @type {object}\n * @default {}\n */\n this.feedOpts || (this.feedOpts = {})\n utils.fillIn(this.feedOpts, FEED_OPTS_DEFAULTS)\n\n /**\n * Override the default predicate functions for the specified operators.\n *\n * @name DocumentDBAdapter#operators\n * @type {object}\n * @default {}\n */\n this.operators || (this.operators = {})\n utils.fillIn(this.operators, OPERATORS)\n\n /**\n * Options to pass to a new `DocumentClient` instance, if one was not provided\n * at {@link DocumentDBAdapter#client}. See the [DocumentClient API][readme]\n * for instance options.\n *\n * [readme]: http://azure.github.io/azure-documentdb-node/DocumentClient.html\n *\n * @name DocumentDBAdapter#documentOpts\n * @see http://azure.github.io/azure-documentdb-node/DocumentClient.html\n * @type {object}\n * @property {string} db The default database to use.\n * @property {string} urlConnection The service endpoint to use to create the\n * client.\n * @property {object} auth An object that is used for authenticating requests\n * and must contains one of the auth options.\n * @property {object} auth.masterkey The authorization master key to use to\n * create the client.\n * Keys for the object are resource Ids and values are the resource tokens.\n * @property {object[]} auth.resourceTokens An object that contains resources tokens.\n * Keys for the object are resource Ids and values are the resource tokens.\n * @property {string} auth.permissionFeed An array of Permission objects.\n * @property {string} [connectionPolicy] An instance of ConnectionPolicy class.\n * This parameter is optional and the default connectionPolicy will be used if\n * omitted.\n * @property {string} [consistencyLevel] An optional parameter that represents\n * the consistency level. It can take any value from ConsistencyLevel.\n */\n this.documentOpts || (this.documentOpts = {})\n\n if (!this.client) {\n this.client = new DocumentClient(\n this.documentOpts.urlConnection,\n this.documentOpts.auth,\n this.documentOpts.connectionPolicy,\n this.documentOpts.consistencyLevel\n )\n }\n}\n\nAdapter.extend({\n constructor: DocumentDBAdapter,\n\n _count (mapper, query, opts) {\n opts || (opts = {})\n query || (query = {})\n\n const collectionId = mapper.collection || underscore(mapper.name)\n opts.select = `${collectionId}.${mapper.idAttribute}`\n\n return this._findAll(mapper, query, opts)\n .then((result) => [result[0].length, { found: result[0].length }])\n },\n\n _create (mapper, props, opts) {\n props || (props = {})\n opts || (opts = {})\n\n return new utils.Promise((resolve, reject) => {\n this.client.createDocument(\n this.getCollectionLink(mapper, opts),\n utils.plainCopy(props),\n this.getOpt('requestOpts', opts),\n (err, document) => {\n if (err) {\n return reject(err)\n }\n return resolve([document, { created: 1 }])\n }\n )\n })\n },\n\n _createMany (mapper, props, opts) {\n props || (props = {})\n opts || (opts = {})\n\n return utils.Promise.all(props.map((record) => this._create(mapper, record, opts)))\n .then((results) => results.map((result) => result[0]))\n .then((results) => [results, { created: results.length }])\n },\n\n _destroy (mapper, id, opts) {\n opts || (opts = {})\n\n const collLink = this.getCollectionLink(mapper, opts)\n const requestOpts = this.getOpt('requestOpts', opts)\n\n return new utils.Promise((resolve, reject) => {\n this.client.deleteDocument(`${collLink}/docs/${id}`, requestOpts, (err) => {\n if (err) {\n if (err.code === 404) {\n return resolve([undefined, { deleted: 0 }])\n }\n return reject(err)\n }\n return resolve([undefined, { deleted: 1 }])\n })\n })\n },\n\n _destroyAll (mapper, query, opts) {\n query || (query = {})\n opts || (opts = {})\n\n const destroyFn = (document) => this._destroy(mapper, document.id, opts)\n\n return this._findAll(mapper, query, opts)\n .then((results) => utils.Promise.all(results[0].map(destroyFn)))\n .then((results) => [undefined, { deleted: results.length }])\n },\n\n _find (mapper, id, opts) {\n opts || (opts = {})\n\n const docLink = `${this.getCollectionLink(mapper, opts)}/docs/${id}`\n const requestOpts = this.getOpt('requestOpts', opts)\n\n return new utils.Promise((resolve, reject) => {\n this.client.readDocument(docLink, requestOpts, (err, document) => {\n if (err) {\n if (err.code === 404) {\n return resolve([undefined, { found: 0 }])\n }\n return reject(err)\n }\n return resolve([document, { found: document ? 1 : 0 }])\n })\n })\n },\n\n _findAll (mapper, query, opts) {\n opts || (opts = {})\n query || (query = {})\n\n const collLink = this.getCollectionLink(mapper, opts)\n const feedOpts = this.getOpt('feedOpts', opts)\n const querySpec = this.getQuerySpec(mapper, query, opts)\n\n return new utils.Promise((resolve, reject) => {\n this.client.queryDocuments(collLink, querySpec, feedOpts).toArray((err, documents) => {\n if (err) {\n return reject(err)\n }\n return resolve([documents, { found: documents.length }])\n })\n })\n },\n\n _sum (mapper, field, query, opts) {\n if (!utils.isString(field)) {\n throw new Error('field must be a string!')\n }\n opts || (opts = {})\n query || (query = {})\n\n const collectionId = mapper.collection || underscore(mapper.name)\n opts.select = `${collectionId}.${mapper.idAttribute}, ${collectionId}.${field}`\n\n return this._findAll(mapper, query, opts)\n .then((result) => {\n const sum = result[0].reduce((sum, cur) => sum + cur[field], 0)\n return [sum, { found: result[0].length }]\n })\n },\n\n _update (mapper, id, props, opts) {\n props || (props = {})\n opts || (opts = {})\n\n const docLink = `${this.getCollectionLink(mapper, opts)}/docs/${id}`\n const requestOpts = this.getOpt('requestOpts', opts)\n\n return this._find(mapper, id, opts)\n .then((result) => {\n const document = result[0]\n if (!document) {\n throw new Error('Not Found')\n }\n utils.deepMixIn(document, utils.plainCopy(props))\n return new utils.Promise((resolve, reject) => {\n this.client.replaceDocument(docLink, document, requestOpts, (err, updatedDocument) => {\n if (err) {\n return reject(err)\n }\n return resolve([updatedDocument, { updated: updatedDocument ? 1 : 0 }])\n })\n })\n })\n },\n\n _updateAll (mapper, props, query, opts) {\n props || (props = {})\n query || (query = {})\n opts || (opts = {})\n\n props = utils.plainCopy(props)\n\n const requestOpts = this.getOpt('requestOpts', opts)\n const collLink = this.getCollectionLink(mapper, opts)\n\n return this._findAll(mapper, query, opts)\n .then((result) => {\n const documents = result[0]\n documents.forEach((document) => {\n utils.deepMixIn(document, props)\n })\n return utils.Promise.all(documents.map((document) => {\n return new utils.Promise((resolve, reject) => {\n const docLink = `${collLink}/docs/${document.id}`\n this.client.replaceDocument(docLink, document, requestOpts, (err, updatedDocument) => {\n if (err) {\n return reject(err)\n }\n return resolve(updatedDocument)\n })\n })\n }))\n })\n .then((documents) => [documents, { updated: documents.length }])\n },\n\n _updateMany (mapper, records, opts) {\n records || (records = [])\n opts || (opts = {})\n\n records = records.filter((record) => record && record.id !== undefined)\n\n return utils.Promise.all(records.map((record) => this._update(mapper, record.id, record, opts)))\n .then((results) => [results.map((result) => result[0]), { updated: results.length }])\n },\n\n _applyWhereFromObject (where) {\n const fields = []\n const ops = []\n const predicates = []\n utils.forOwn(where, (clause, field) => {\n if (!utils.isObject(clause)) {\n clause = {\n '==': clause\n }\n }\n utils.forOwn(clause, (expr, op) => {\n fields.push(field)\n ops.push(op)\n predicates.push(expr)\n })\n })\n return {\n fields,\n ops,\n predicates\n }\n },\n\n _applyWhereFromArray (where) {\n const groups = []\n where.forEach((_where, i) => {\n if (utils.isString(_where)) {\n return\n }\n const prev = where[i - 1]\n const parser = utils.isArray(_where) ? this._applyWhereFromArray : this._applyWhereFromObject\n const group = parser.call(this, _where)\n if (prev === 'or') {\n group.isOr = true\n }\n groups.push(group)\n })\n groups.isArray = true\n return groups\n },\n\n _testObjectGroup (sql, group, parameters, collectionId, opts) {\n let i\n const fields = group.fields\n const ops = group.ops\n const predicates = group.predicates\n const len = ops.length\n for (i = 0; i < len; i++) {\n let op = ops[i]\n const isOr = op.charAt(0) === '|'\n op = isOr ? op.substr(1) : op\n const predicateFn = this.getOperator(op, opts)\n if (predicateFn) {\n const subSql = predicateFn(fields[i], predicates[i], parameters, collectionId)\n if (isOr) {\n sql = sql ? `${sql} OR (${subSql})` : `(${subSql})`\n } else {\n sql = sql ? `${sql} AND (${subSql})` : `(${subSql})`\n }\n } else {\n throw new Error(`Operator ${op} not supported!`)\n }\n }\n return sql\n },\n\n _testArrayGroup (sql, groups, parameters, collectionId, opts) {\n let i\n const len = groups.length\n for (i = 0; i < len; i++) {\n const group = groups[i]\n let subQuery\n if (group.isArray) {\n subQuery = this._testArrayGroup(sql, group, parameters, collectionId, opts)\n } else {\n subQuery = this._testObjectGroup(null, group, parameters, collectionId, opts)\n }\n if (groups[i - 1]) {\n if (group.isOr) {\n sql += ` OR (${subQuery})`\n } else {\n sql += ` AND (${subQuery})`\n }\n } else {\n sql = sql ? sql + ` AND (${subQuery})` : `(${subQuery})`\n }\n }\n return sql\n },\n\n /**\n * Generate the querySpec object for DocumentClient#queryDocuments.\n *\n * @name DocumentDBAdapter#getQuerySpec\n * @method\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 {object} [opts.operators] Override the default predicate functions\n * for specified operators.\n */\n getQuerySpec (mapper, query, opts) {\n query = utils.plainCopy(query || {})\n opts || (opts = {})\n opts.operators || (opts.operators = {})\n query.where || (query.where = {})\n query.orderBy || (query.orderBy = query.sort)\n query.orderBy || (query.orderBy = [])\n query.skip || (query.skip = query.offset)\n const collectionId = mapper.collection || underscore(mapper.name)\n\n const select = opts.select || '*'\n let sql = `${select} FROM ${collectionId}`\n let whereSql\n const parameters = []\n\n // Transform non-keyword properties to \"where\" clause configuration\n utils.forOwn(query, (config, keyword) => {\n if (reserved.indexOf(keyword) === -1 && utils.isObject(query.where)) {\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 // Filter\n let groups\n\n if (utils.isObject(query.where) && Object.keys(query.where).length !== 0) {\n groups = this._applyWhereFromArray([query.where])\n } else if (utils.isArray(query.where)) {\n groups = this._applyWhereFromArray(query.where)\n }\n\n if (groups) {\n whereSql = this._testArrayGroup(null, groups, parameters, collectionId, opts)\n }\n\n if (whereSql) {\n sql = `${sql} WHERE ${whereSql}`\n }\n\n // Sort\n let orderBySql = ''\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 const subOrderBySql = (query.orderBy[i][1] || '').toUpperCase() === 'DESC' ? `${collectionId}.${query.orderBy[i][0]} DESC` : `${collectionId}.${query.orderBy[i][0]}`\n if (orderBySql) {\n orderBySql = `${orderBySql}, ${subOrderBySql}`\n } else {\n orderBySql = subOrderBySql\n }\n }\n if (orderBySql) {\n orderBySql = `ORDER BY ${orderBySql}`\n }\n }\n\n // Offset\n // if (query.skip) {\n // sql += ` SKIP ${+query.skip}`\n // }\n\n // Limit\n if (query.limit) {\n sql = `TOP ${+query.limit} ${sql}`\n }\n\n sql = `SELECT ${sql}` + (orderBySql ? ` ${orderBySql}` : '')\n return {\n query: sql,\n parameters\n }\n },\n\n getDbLink (opts) {\n return `dbs/${opts.db === undefined ? this.documentOpts.db : opts.db}`\n },\n\n getCollectionLink (mapper, opts) {\n return `${this.getDbLink(opts)}/colls/${mapper.collection || underscore(mapper.name)}`\n },\n\n waitForDb (opts) {\n opts || (opts = {})\n const dbId = utils.isUndefined(opts.db) ? this.documentOpts.db : opts.db\n if (!this.databases[dbId]) {\n this.databases[dbId] = new utils.Promise((resolve, reject) => {\n this.client.readDatabases().toArray((err, dbs) => {\n if (err) {\n return reject(err)\n }\n let existing\n dbs.forEach((db) => {\n if (dbId === db.id) {\n existing = db\n return false\n }\n })\n if (!existing) {\n return this.client.createDatabase({ id: dbId }, (err, db) => {\n if (err) {\n return reject(err)\n }\n return resolve(db)\n })\n }\n return resolve(existing)\n })\n })\n }\n return this.databases[dbId]\n },\n\n waitForCollection (mapper, opts) {\n opts || (opts = {})\n const collectionId = utils.isString(mapper) ? mapper : (mapper.collection || underscore(mapper.name))\n let dbId = utils.isUndefined(opts.db) ? this.documentOpts.db : opts.db\n return this.waitForDb(opts).then(() => {\n this.collections[dbId] = this.collections[dbId] || {}\n if (!this.collections[dbId][collectionId]) {\n this.collections[dbId][collectionId] = new utils.Promise((resolve, reject) => {\n this.client.readCollections(`dbs/${dbId}`).toArray((err, collections) => {\n if (err) {\n return reject(err)\n }\n let existing\n collections.forEach((collection) => {\n if (collectionId === collection.id) {\n existing = collection\n return false\n }\n })\n if (!existing) {\n return this.client.createCollection(`dbs/${dbId}`, { id: collectionId }, (err, collection) => {\n if (err) {\n return reject(err)\n }\n return resolve(collection)\n })\n }\n return resolve(existing)\n })\n })\n }\n return this.collections[dbId][collectionId]\n })\n },\n\n /**\n * Return the number of records that match the selection query.\n *\n * @name DocumentDBAdapter#count\n * @method\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 {object} [opts.operators] Override the default predicate functions\n * for specified operators.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * response object.\n * @param {object} [opts.requestOpts] Options to pass to the DocumentClient request.\n * @return {Promise}\n */\n count (mapper, query, opts) {\n opts || (opts = {})\n query || (query = {})\n\n return this.waitForCollection(mapper, opts)\n .then(() => Adapter.prototype.count.call(this, mapper, query, opts))\n },\n\n /**\n * Create a new record.\n *\n * @name DocumentDBAdapter#create\n * @method\n * @param {object} mapper The mapper.\n * @param {object} props The record to be created.\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.requestOpts] Options to pass to the DocumentClient request.\n * @return {Promise}\n */\n create (mapper, props, opts) {\n props || (props = {})\n opts || (opts = {})\n\n return this.waitForCollection(mapper, opts)\n .then(() => Adapter.prototype.create.call(this, mapper, props, opts))\n },\n\n /**\n * Create multiple records in a single batch.\n *\n * @name DocumentDBAdapter#createMany\n * @method\n * @param {object} mapper The mapper.\n * @param {object} props The records to be created.\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.requestOpts] Options to pass to the DocumentClient request.\n * @return {Promise}\n */\n createMany (mapper, props, opts) {\n props || (props = {})\n opts || (opts = {})\n\n return this.waitForCollection(mapper, opts)\n .then(() => Adapter.prototype.createMany.call(this, mapper, props, opts))\n },\n\n /**\n * Destroy the record with the given primary key.\n *\n * @name DocumentDBAdapter#destroy\n * @method\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.requestOpts] Options to pass to the DocumentClient request.\n * @return {Promise}\n */\n destroy (mapper, id, opts) {\n opts || (opts = {})\n\n return this.waitForCollection(mapper, opts)\n .then(() => Adapter.prototype.destroy.call(this, mapper, id, opts))\n },\n\n /**\n * Destroy the records that match the selection query.\n *\n * @name DocumentDBAdapter#destroyAll\n * @method\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 {object} [opts.feedOpts] Options to pass to the DocumentClient#queryDocuments.\n * @param {object} [opts.operators] Override the default predicate functions\n * for specified operators.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * response object.\n * @param {object} [opts.requestOpts] Options to pass to the DocumentClient request.\n * @return {Promise}\n */\n destroyAll (mapper, query, opts) {\n opts || (opts = {})\n query || (query = {})\n\n return this.waitForCollection(mapper, opts)\n .then(() => Adapter.prototype.destroyAll.call(this, mapper, query, opts))\n },\n\n /**\n * Retrieve the record with the given primary key.\n *\n * @name DocumentDBAdapter#find\n * @method\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 {boolean} [opts.raw=false] Whether to return a more detailed\n * response object.\n * @param {object} [opts.requestOpts] Options to pass to the DocumentClient request.\n * @param {string[]} [opts.with=[]] Relations to eager load.\n * @return {Promise}\n */\n find (mapper, id, opts) {\n opts || (opts = {})\n\n return this.waitForCollection(mapper, opts)\n .then(() => Adapter.prototype.find.call(this, mapper, id, opts))\n },\n\n /**\n * Retrieve the records that match the selection query.\n *\n * @name DocumentDBAdapter#findAll\n * @method\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 {object} [opts.feedOpts] Options to pass to the DocumentClient#queryDocuments.\n * @param {object} [opts.operators] Override the default predicate functions\n * for specified operators.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * response object.\n * @param {object} [opts.requestOpts] Options to pass to the DocumentClient request.\n * @param {string[]} [opts.with=[]] Relations to eager load.\n * @return {Promise}\n */\n findAll (mapper, query, opts) {\n opts || (opts = {})\n query || (query = {})\n\n return this.waitForCollection(mapper, opts)\n .then(() => Adapter.prototype.findAll.call(this, mapper, query, opts))\n },\n\n /**\n * Resolve the predicate function for the specified operator based on the\n * given options and this adapter's settings.\n *\n * @name DocumentDBAdapter#getOperator\n * @method\n * @param {string} operator The name of the operator.\n * @param {object} [opts] Configuration options.\n * @param {object} [opts.operators] Override the default predicate functions\n * for specified operators.\n * @return {*} The predicate function for the specified operator.\n */\n getOperator (operator, opts) {\n opts || (opts = {})\n opts.operators || (opts.operators = {})\n let ownOps = this.operators || {}\n return utils.isUndefined(opts.operators[operator]) ? ownOps[operator] : opts.operators[operator]\n },\n\n /**\n * Return the sum of the specified field of records that match the selection\n * query.\n *\n * @name DocumentDBAdapter#sum\n * @method\n * @param {object} mapper The mapper.\n * @param {string} field The field to sum.\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 {object} [opts.feedOpts] Options to pass to the DocumentClient#queryDocuments.\n * @param {object} [opts.operators] Override the default predicate functions\n * for specified operators.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * response object.\n * @param {object} [opts.requestOpts] Options to pass to the DocumentClient request.\n * @return {Promise}\n */\n sum (mapper, field, query, opts) {\n opts || (opts = {})\n query || (query = {})\n\n return this.waitForCollection(mapper, opts)\n .then(() => Adapter.prototype.sum.call(this, mapper, field, query, opts))\n },\n\n /**\n * Apply the given update to the record with the specified primary key.\n *\n * @name DocumentDBAdapter#update\n * @method\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.requestOpts] Options to pass to the DocumentClient request.\n * @return {Promise}\n */\n update (mapper, id, props, opts) {\n props || (props = {})\n opts || (opts = {})\n\n return this.waitForCollection(mapper, opts)\n .then(() => Adapter.prototype.update.call(this, mapper, id, props, opts))\n },\n\n /**\n * Apply the given update to all records that match the selection query.\n *\n * @name DocumentDBAdapter#updateAll\n * @method\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} [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 {object} [opts.feedOpts] Options to pass to the DocumentClient#queryDocuments.\n * @param {object} [opts.operators] Override the default predicate functions\n * for specified operators.\n * @param {boolean} [opts.raw=false] Whether to return a more detailed\n * response object.\n * @param {object} [opts.requestOpts] Options to pass to the DocumentClient request.\n * @return {Promise}\n */\n updateAll (mapper, props, query, opts) {\n props || (props = {})\n query || (query = {})\n opts || (opts = {})\n\n return this.waitForCollection(mapper, opts)\n .then(() => Adapter.prototype.updateAll.call(this, mapper, props, query, opts))\n },\n\n /**\n * Update the given records in a single batch.\n *\n * @name DocumentDBAdapter#updateMany\n * @method\n * @param {object} mapper The mapper.\n * @param {Object[]} records The records to update.\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.requestOpts] Options to pass to the DocumentClient request.\n * @return {Promise}\n */\n updateMany (mapper, records, opts) {\n records || (records = [])\n opts || (opts = {})\n\n return this.waitForCollection(mapper, opts)\n .then(() => Adapter.prototype.updateMany.call(this, mapper, records, opts))\n }\n})\n\n/**\n * Details of the current version of the `js-data-documentdb` module.\n *\n * @example ES2015 modules import\n * import {version} from 'js-data-documentdb'\n * console.log(version.full)\n *\n * @example CommonJS import\n * var version = require('js-data-documentdb').version\n * console.log(version.full)\n *\n * @name module:js-data-documentdb.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 DocumentDBAdapter} class.\n *\n * @example ES2015 modules import\n * import {DocumentDBAdapter} from 'js-data-documentdb'\n * const adapter = new DocumentDBAdapter()\n *\n * @example CommonJS import\n * var DocumentDBAdapter = require('js-data-documentdb').DocumentDBAdapter\n * var adapter = new DocumentDBAdapter()\n *\n * @name module:js-data-documentdb.DocumentDBAdapter\n * @see DocumentDBAdapter\n * @type {Constructor}\n */\n\n/**\n * Registered as `js-data-documentdb` in NPM.\n *\n * @example Install from NPM\n * npm i --save js-data-documentdb js-data documentdb\n *\n * @example ES2015 modules import\n * import { DocumentDBAdapter } from 'js-data-documentdb'\n * const adapter = new DocumentDBAdapter({\n * documentOpts: {\n * db: 'mydb',\n * urlConnection: process.env.DOCUMENT_DB_ENDPOINT,\n * auth: {\n * masterKey: process.env.DOCUMENT_DB_KEY\n * }\n * }\n * })\n *\n * @example CommonJS import\n * var DocumentDBAdapter = require('js-data-documentdb').DocumentDBAdapter\n * var adapter = new DocumentDBAdapter({\n * documentOpts: {\n * db: 'mydb',\n * urlConnection: process.env.DOCUMENT_DB_ENDPOINT,\n * auth: {\n * masterKey: process.env.DOCUMENT_DB_KEY\n * }\n * }\n * })\n *\n * @module js-data-documentdb\n */\n\n/**\n * Create a subclass of this DocumentDBAdapter:\n * @example DocumentDBAdapter.extend\n * // Normally you would do: import {DocumentDBAdapter} from 'js-data-documentdb'\n * const JSDataDocumentDB = require('js-data-documentdb')\n * const { DocumentDBAdapter } = JSDataDocumentDB\n * console.log('Using JSDataDocumentDB v' + JSDataDocumentDB.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomDocumentDBAdapterClass extends DocumentDBAdapter {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customDocumentDBAdapter = new CustomDocumentDBAdapterClass({\n * documentOpts: {\n * db: 'mydb',\n * urlConnection: process.env.DOCUMENT_DB_ENDPOINT,\n * auth: {\n * masterKey: process.env.DOCUMENT_DB_KEY\n * }\n * }\n * })\n * console.log(customDocumentDBAdapter.foo())\n * console.log(CustomDocumentDBAdapterClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherDocumentDBAdapterClass = DocumentDBAdapter.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherDocumentDBAdapter = new OtherDocumentDBAdapterClass({\n * documentOpts: {\n * db: 'mydb',\n * urlConnection: process.env.DOCUMENT_DB_ENDPOINT,\n * auth: {\n * masterKey: process.env.DOCUMENT_DB_KEY\n * }\n * }\n * })\n * console.log(otherDocumentDBAdapter.foo())\n * console.log(OtherDocumentDBAdapterClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherDocumentDBAdapterClass () {\n * DocumentDBAdapter.call(this)\n * this.created_at = new Date().getTime()\n * }\n * DocumentDBAdapter.extend({\n * constructor: AnotherDocumentDBAdapterClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherDocumentDBAdapter = new AnotherDocumentDBAdapterClass({\n * documentOpts: {\n * db: 'mydb',\n * urlConnection: process.env.DOCUMENT_DB_ENDPOINT,\n * auth: {\n * masterKey: process.env.DOCUMENT_DB_KEY\n * }\n * }\n * })\n * console.log(anotherDocumentDBAdapter.created_at)\n * console.log(anotherDocumentDBAdapter.foo())\n * console.log(AnotherDocumentDBAdapterClass.beep())\n *\n * @method DocumentDBAdapter.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 DocumentDBAdapter class.\n * @since 3.0.0\n */\n"],"names":["DocumentClient","Adapter","utils","reserved"],"mappings":"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"} \ No newline at end of file