From 81ddf9b700bc48a1f8e472209f080f9c1d9a9b09 Mon Sep 17 00:00:00 2001 From: Piotr Russ Date: Wed, 18 Nov 2020 23:26:45 +0100 Subject: rm node_modules --- node_modules/mquery/.eslintignore | 1 - node_modules/mquery/.travis.yml | 17 - node_modules/mquery/History.md | 342 -- node_modules/mquery/LICENSE | 22 - node_modules/mquery/Makefile | 26 - node_modules/mquery/README.md | 1375 --------- node_modules/mquery/lib/collection/collection.js | 46 - node_modules/mquery/lib/collection/index.js | 13 - node_modules/mquery/lib/collection/node.js | 151 - node_modules/mquery/lib/env.js | 22 - node_modules/mquery/lib/mquery.js | 3252 -------------------- node_modules/mquery/lib/permissions.js | 88 - node_modules/mquery/lib/utils.js | 356 --- .../mquery/node_modules/debug/.coveralls.yml | 1 - node_modules/mquery/node_modules/debug/.eslintrc | 14 - node_modules/mquery/node_modules/debug/.npmignore | 9 - node_modules/mquery/node_modules/debug/.travis.yml | 20 - .../mquery/node_modules/debug/CHANGELOG.md | 395 --- node_modules/mquery/node_modules/debug/LICENSE | 19 - node_modules/mquery/node_modules/debug/Makefile | 58 - node_modules/mquery/node_modules/debug/README.md | 368 --- .../mquery/node_modules/debug/karma.conf.js | 70 - node_modules/mquery/node_modules/debug/node.js | 1 - .../mquery/node_modules/debug/package.json | 82 - .../mquery/node_modules/debug/src/browser.js | 195 -- .../mquery/node_modules/debug/src/debug.js | 225 -- .../mquery/node_modules/debug/src/index.js | 10 - node_modules/mquery/node_modules/debug/src/node.js | 186 -- node_modules/mquery/package.json | 114 - node_modules/mquery/test/collection/browser.js | 0 node_modules/mquery/test/collection/mongo.js | 0 node_modules/mquery/test/collection/node.js | 28 - node_modules/mquery/test/env.js | 21 - node_modules/mquery/test/index.js | 3076 ------------------ node_modules/mquery/test/utils.test.js | 144 - 35 files changed, 10747 deletions(-) delete mode 100644 node_modules/mquery/.eslintignore delete mode 100644 node_modules/mquery/.travis.yml delete mode 100644 node_modules/mquery/History.md delete mode 100644 node_modules/mquery/LICENSE delete mode 100644 node_modules/mquery/Makefile delete mode 100644 node_modules/mquery/README.md delete mode 100644 node_modules/mquery/lib/collection/collection.js delete mode 100644 node_modules/mquery/lib/collection/index.js delete mode 100644 node_modules/mquery/lib/collection/node.js delete mode 100644 node_modules/mquery/lib/env.js delete mode 100644 node_modules/mquery/lib/mquery.js delete mode 100644 node_modules/mquery/lib/permissions.js delete mode 100644 node_modules/mquery/lib/utils.js delete mode 100644 node_modules/mquery/node_modules/debug/.coveralls.yml delete mode 100644 node_modules/mquery/node_modules/debug/.eslintrc delete mode 100644 node_modules/mquery/node_modules/debug/.npmignore delete mode 100644 node_modules/mquery/node_modules/debug/.travis.yml delete mode 100644 node_modules/mquery/node_modules/debug/CHANGELOG.md delete mode 100644 node_modules/mquery/node_modules/debug/LICENSE delete mode 100644 node_modules/mquery/node_modules/debug/Makefile delete mode 100644 node_modules/mquery/node_modules/debug/README.md delete mode 100644 node_modules/mquery/node_modules/debug/karma.conf.js delete mode 100644 node_modules/mquery/node_modules/debug/node.js delete mode 100644 node_modules/mquery/node_modules/debug/package.json delete mode 100644 node_modules/mquery/node_modules/debug/src/browser.js delete mode 100644 node_modules/mquery/node_modules/debug/src/debug.js delete mode 100644 node_modules/mquery/node_modules/debug/src/index.js delete mode 100644 node_modules/mquery/node_modules/debug/src/node.js delete mode 100644 node_modules/mquery/package.json delete mode 100644 node_modules/mquery/test/collection/browser.js delete mode 100644 node_modules/mquery/test/collection/mongo.js delete mode 100644 node_modules/mquery/test/collection/node.js delete mode 100644 node_modules/mquery/test/env.js delete mode 100644 node_modules/mquery/test/index.js delete mode 100644 node_modules/mquery/test/utils.test.js (limited to 'node_modules/mquery') diff --git a/node_modules/mquery/.eslintignore b/node_modules/mquery/.eslintignore deleted file mode 100644 index 4b4d863..0000000 --- a/node_modules/mquery/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -coverage/ \ No newline at end of file diff --git a/node_modules/mquery/.travis.yml b/node_modules/mquery/.travis.yml deleted file mode 100644 index 3d207e1..0000000 --- a/node_modules/mquery/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -language: node_js -node_js: - - "8" - - "10" - - "12" -matrix: - include: - - node_js: "13" - env: "NVM_NODEJS_ORG_MIRROR=https://nodejs.org/download/nightly" - allow_failures: - # Allow the nightly installs to fail - - env: "NVM_NODEJS_ORG_MIRROR=https://nodejs.org/download/nightly" -script: - - npm test - - npm run lint -services: - - mongodb diff --git a/node_modules/mquery/History.md b/node_modules/mquery/History.md deleted file mode 100644 index bc6a3c3..0000000 --- a/node_modules/mquery/History.md +++ /dev/null @@ -1,342 +0,0 @@ -3.2.2 / 2019-09-22 -================== - * fix: dont re-call setOptions() when pulling base class options Automattic/mongoose#8159 - -3.2.1 / 2018-08-24 -================== - * chore: upgrade deps - -3.2.0 / 2018-08-24 -================== - * feat: add $useProjection to opt in to using `projection` instead of `fields` re: MongoDB deprecation warnings Automattic/mongoose#6880 - -3.1.2 / 2018-08-01 -================== - * chore: move eslint to devDependencies #110 [jakesjews](https://github.com/jakesjews) - -3.1.1 / 2018-07-30 -================== - * chore: add eslint #107 [Fonger](https://github.com/Fonger) - * docs: clean up readConcern docs #106 [Fonger](https://github.com/Fonger) - -3.1.0 / 2018-07-29 -================== - * feat: add `readConcern()` helper #105 [Fonger](https://github.com/Fonger) - * feat: add `maxTimeMS()` as alias of `maxTime()` #105 [Fonger](https://github.com/Fonger) - * feat: add `collation()` helper #105 [Fonger](https://github.com/Fonger) - -3.0.1 / 2018-07-02 -================== - * fix: parse sort array options correctly #103 #102 [Fonger](https://github.com/Fonger) - -3.0.0 / 2018-01-20 -================== - * chore: upgrade deps and add nsp - -3.0.0-rc0 / 2017-12-06 -====================== - * BREAKING CHANGE: remove support for node < 4 - * BREAKING CHANGE: remove support for retainKeyOrder, will always be true by default re: Automattic/mongoose#2749 - -2.3.3 / 2017-11-19 -================== - * fixed; catch sync errors in cursor.toArray() re: Automattic/mongoose#5812 - -2.3.2 / 2017-09-27 -================== - * fixed; bumped debug -> 2.6.9 re: #89 - -2.3.1 / 2017-05-22 -================== - * fixed; bumped debug -> 2.6.7 re: #86 - -2.3.0 / 2017-03-05 -================== - * added; replaceOne function - * added; deleteOne and deleteMany functions - -2.2.3 / 2017-01-31 -================== - * fixed; throw correct error when passing incorrectly formatted array to sort() - -2.2.2 / 2017-01-31 -================== - * fixed; allow passing maps to sort() - -2.2.1 / 2017-01-29 -================== - * fixed; allow passing string to hint() - -2.2.0 / 2017-01-08 -================== - * added; updateOne and updateMany functions - -2.1.0 / 2016-12-22 -================== - * added; ability to pass an array to select() #81 [dciccale](https://github.com/dciccale) - -2.0.0 / 2016-09-25 -================== - * added; support for mongodb driver 2.0 streams - -1.12.0 / 2016-09-25 -=================== - * added; `retainKeyOrder` option re: Automattic/mongoose#4542 - -1.11.0 / 2016-06-04 -=================== - * added; `.minDistance()` helper and minDistance for `.near()` Automattic/mongoose#4179 - -1.10.1 / 2016-04-26 -=================== - * fixed; ensure conditions is an object before assigning #75 - -1.10.0 / 2016-03-16 -================== - - * updated; bluebird to latest 2.10.2 version #74 [matskiv](https://github.com/matskiv) - -1.9.0 / 2016-03-15 -================== - * added; `.eq` as a shortcut for `.equals` #72 [Fonger](https://github.com/Fonger) - * added; ability to use array syntax for sort re: https://jira.mongodb.org/browse/NODE-578 #67 - -1.8.0 / 2016-03-01 -================== - * fixed; dont throw an error if count used with sort or select Automattic/mongoose#3914 - -1.7.0 / 2016-02-23 -================== - * fixed; don't treat objects with a length property as argument objects #70 - * added; `.findCursor()` method #69 [nswbmw](https://github.com/nswbmw) - * added; `_compiledUpdate` property #68 [nswbmw](https://github.com/nswbmw) - -1.6.2 / 2015-07-12 -================== - - * fixed; support exec cb being called synchronously #66 - -1.6.1 / 2015-06-16 -================== - - * fixed; do not treat $meta projection as inclusive [vkarpov15](https://github.com/vkarpov15) - -1.6.0 / 2015-05-27 -================== - - * update dependencies #65 [bachp](https://github.com/bachp) - -1.5.0 / 2015-03-31 -================== - - * fixed; debug output - * fixed; allow hint usage with count #61 [trueinsider](https://github.com/trueinsider) - -1.4.0 / 2015-03-29 -================== - - * added; object support to slice() #60 [vkarpov15](https://github.com/vkarpov15) - * debug; improved output #57 [flyvictor](https://github.com/flyvictor) - -1.3.0 / 2014-11-06 -================== - - * added; setTraceFunction() #53 from [jlai](https://github.com/jlai) - -1.2.1 / 2014-09-26 -================== - - * fixed; distinct assignment in toConstructor() #51 from [esco](https://github.com/esco) - -1.2.0 / 2014-09-18 -================== - - * added; stream() support for find() - -1.1.0 / 2014-09-15 -================== - - * add #then for co / koa support - * start checking code coverage - -1.0.0 / 2014-07-07 -================== - - * Remove broken require() calls until they're actually implemented #48 [vkarpov15](https://github.com/vkarpov15) - -0.9.0 / 2014-05-22 -================== - - * added; thunk() support - * release 0.8.0 - -0.8.0 / 2014-05-15 -================== - - * added; support for maxTimeMS #44 [yoitsro](https://github.com/yoitsro) - * updated; devDependency (driver to 1.4.4) - -0.7.0 / 2014-05-02 -================== - - * fixed; pass $maxDistance in $near object as described in docs #43 [vkarpov15](https://github.com/vkarpov15) - * fixed; cloning buffers #42 [gjohnson](https://github.com/gjohnson) - * tests; a little bit more `mongodb` agnostic #34 [refack](https://github.com/refack) - -0.6.0 / 2014-04-01 -================== - - * fixed; Allow $meta args in sort() so text search sorting works #37 [vkarpov15](https://github.com/vkarpov15) - -0.5.3 / 2014-02-22 -================== - - * fixed; cloning mongodb.Binary - -0.5.2 / 2014-01-30 -================== - - * fixed; cloning ObjectId constructors - * fixed; cloning of ReadPreferences #30 [ashtuchkin](https://github.com/ashtuchkin) - * tests; use specific mongodb version #29 [AvianFlu](https://github.com/AvianFlu) - * tests; remove dependency on ObjectId #28 [refack](https://github.com/refack) - * tests; add failing ReadPref test - -0.5.1 / 2014-01-17 -================== - - * added; deprecation notice to tags parameter #27 [ashtuchkin](https://github.com/ashtuchkin) - * readme; add links - -0.5.0 / 2014-01-16 -================== - - * removed; mongodb driver dependency #26 [ashtuchkin](https://github.com/ashtuchkin) - * removed; first class support of read preference tags #26 (still supported though) [ashtuchkin](https://github.com/ashtuchkin) - * added; better ObjectId clone support - * fixed; cloning objects that have no constructor #21 - * docs; cleaned up [ashtuchkin](https://github.com/ashtuchkin) - -0.4.2 / 2014-01-08 -================== - - * updated; debug module 0.7.4 [refack](https://github.com/refack) - -0.4.1 / 2014-01-07 -================== - - * fixed; inclusive/exclusive logic - -0.4.0 / 2014-01-06 -================== - - * added; selected() - * added; selectedInclusively() - * added; selectedExclusively() - -0.3.3 / 2013-11-14 -================== - - * Fix Mongo DB Dependency #20 [rschmukler](https://github.com/rschmukler) - -0.3.2 / 2013-09-06 -================== - - * added; geometry support for near() - -0.3.1 / 2013-08-22 -================== - - * fixed; update retains key order #19 - -0.3.0 / 2013-08-22 -================== - - * less hardcoded isNode env detection #18 [vshulyak](https://github.com/vshulyak) - * added; validation of findAndModify varients - * clone update doc before execution - * stricter env checks - -0.2.7 / 2013-08-2 -================== - - * Now support GeoJSON point values for Query#near - -0.2.6 / 2013-07-30 -================== - - * internally, 'asc' and 'desc' for sorts are now converted into 1 and -1, respectively - -0.2.5 / 2013-07-30 -================== - - * updated docs - * changed internal representation of `sort` to use objects instead of arrays - -0.2.4 / 2013-07-25 -================== - - * updated; sliced to 0.0.5 - -0.2.3 / 2013-07-09 -================== - - * now using a callback in collection.find instead of directly calling toArray() on the cursor [ebensing](https://github.com/ebensing) - -0.2.2 / 2013-07-09 -================== - - * now exposing mongodb export to allow for better testing [ebensing](https://github.com/ebensing) - -0.2.1 / 2013-07-08 -================== - - * select no longer accepts arrays as parameters [ebensing](https://github.com/ebensing) - -0.2.0 / 2013-07-05 -================== - - * use $geoWithin by default - -0.1.2 / 2013-07-02 -================== - - * added use$geoWithin flag [ebensing](https://github.com/ebensing) - * fix read preferences typo [ebensing](https://github.com/ebensing) - * fix reference to old param name in exists() [ebensing](https://github.com/ebensing) - -0.1.1 / 2013-06-24 -================== - - * fixed; $intersects -> $geoIntersects #14 [ebensing](https://github.com/ebensing) - * fixed; Retain key order when copying objects #15 [ebensing](https://github.com/ebensing) - * bump mongodb dev dep - -0.1.0 / 2013-05-06 -================== - - * findAndModify; return the query - * move mquery.proto.canMerge to mquery.canMerge - * overwrite option now works with non-empty objects - * use strict mode - * validate count options - * validate distinct options - * add aggregate to base collection methods - * clone merge arguments - * clone merged update arguments - * move subclass to mquery.prototype.toConstructor - * fixed; maxScan casing - * use regexp-clone - * added; geometry/intersects support - * support $and - * near: do not use "radius" - * callbacks always fire on next turn of loop - * defined collection interface - * remove time from tests - * clarify goals - * updated docs; - -0.0.1 / 2012-12-15 -================== - - * initial release diff --git a/node_modules/mquery/LICENSE b/node_modules/mquery/LICENSE deleted file mode 100644 index 38c529d..0000000 --- a/node_modules/mquery/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2012 [Aaron Heckmann](aaron.heckmann+github@gmail.com) - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/mquery/Makefile b/node_modules/mquery/Makefile deleted file mode 100644 index 587655d..0000000 --- a/node_modules/mquery/Makefile +++ /dev/null @@ -1,26 +0,0 @@ - -test: - @NODE_ENV=test ./node_modules/.bin/mocha $(T) $(TESTS) - -test-cov: - @NODE_ENV=test node \ - node_modules/.bin/istanbul cover \ - ./node_modules/.bin/_mocha \ - -- -u exports \ - -open-cov: - open coverage/lcov-report/index.html - -lint: - @NODE_ENV=test node ./node_modules/eslint/bin/eslint.js . - -test-travis: - @NODE_ENV=test node \ - node_modules/.bin/istanbul cover \ - ./node_modules/.bin/_mocha \ - --report lcovonly \ - --bail - @NODE_ENV=test node \ - ./node_modules/eslint/bin/eslint.js . - -.PHONY: test test-cov open-cov lint test-travis diff --git a/node_modules/mquery/README.md b/node_modules/mquery/README.md deleted file mode 100644 index 58d6322..0000000 --- a/node_modules/mquery/README.md +++ /dev/null @@ -1,1375 +0,0 @@ -# mquery - -`mquery` is a fluent mongodb query builder designed to run in multiple environments. - -[![Build Status](https://travis-ci.org/aheckmann/mquery.svg?branch=master)](https://travis-ci.org/aheckmann/mquery) -[![NPM version](https://badge.fury.io/js/mquery.svg)](http://badge.fury.io/js/mquery) - -[![npm](https://nodei.co/npm/mquery.png)](https://www.npmjs.com/package/mquery) - -## Features - - - fluent query builder api - - custom base query support - - MongoDB 2.4 geoJSON support - - method + option combinations validation - - node.js driver compatibility - - environment detection - - [debug](https://github.com/visionmedia/debug) support - - separated collection implementations for maximum flexibility - -## Use - -```js -require('mongodb').connect(uri, function (err, db) { - if (err) return handleError(err); - - // get a collection - var collection = db.collection('artists'); - - // pass it to the constructor - mquery(collection).find({..}, callback); - - // or pass it to the collection method - mquery().find({..}).collection(collection).exec(callback) - - // or better yet, create a custom query constructor that has it always set - var Artist = mquery(collection).toConstructor(); - Artist().find(..).where(..).exec(callback) -}) -``` - -`mquery` requires a collection object to work with. In the example above we just pass the collection object created using the official [MongoDB driver](https://github.com/mongodb/node-mongodb-native). - - -## Fluent API - -- [find](#find) -- [findOne](#findOne) -- [count](#count) -- [remove](#remove) -- [update](#update) -- [findOneAndUpdate](#findoneandupdate) -- [findOneAndDelete, findOneAndRemove](#findoneandremove) -- [distinct](#distinct) -- [exec](#exec) -- [stream](#stream) -- [all](#all) -- [and](#and) -- [box](#box) -- [circle](#circle) -- [elemMatch](#elemmatch) -- [equals](#equals) -- [exists](#exists) -- [geometry](#geometry) -- [gt](#gt) -- [gte](#gte) -- [in](#in) -- [intersects](#intersects) -- [lt](#lt) -- [lte](#lte) -- [maxDistance](#maxdistance) -- [mod](#mod) -- [ne](#ne) -- [nin](#nin) -- [nor](#nor) -- [near](#near) -- [or](#or) -- [polygon](#polygon) -- [regex](#regex) -- [select](#select) -- [selected](#selected) -- [selectedInclusively](#selectedinclusively) -- [selectedExclusively](#selectedexclusively) -- [size](#size) -- [slice](#slice) -- [within](#within) -- [where](#where) -- [$where](#where-1) -- [batchSize](#batchsize) -- [collation](#collation) -- [comment](#comment) -- [hint](#hint) -- [j](#j) -- [limit](#limit) -- [maxScan](#maxscan) -- [maxTime, maxTimeMS](#maxtime) -- [skip](#skip) -- [sort](#sort) -- [read, setReadPreference](#read) -- [readConcern, r](#readconcern) -- [slaveOk](#slaveok) -- [snapshot](#snapshot) -- [tailable](#tailable) -- [writeConcern, w](#writeconcern) -- [wtimeout, wTimeout](#wtimeout) - -## Helpers - -- [collection](#collection) -- [then](#then) -- [thunk](#thunk) -- [merge](#mergeobject) -- [setOptions](#setoptionsoptions) -- [setTraceFunction](#settracefunctionfunc) -- [mquery.setGlobalTraceFunction](#mquerysetglobaltracefunctionfunc) -- [mquery.canMerge](#mquerycanmerge) -- [mquery.use$geoWithin](#mqueryusegeowithin) - -### find() - -Declares this query a _find_ query. Optionally pass a match clause and / or callback. If a callback is passed the query is executed. - -```js -mquery().find() -mquery().find(match) -mquery().find(callback) -mquery().find(match, function (err, docs) { - assert(Array.isArray(docs)); -}) -``` - -### findOne() - -Declares this query a _findOne_ query. Optionally pass a match clause and / or callback. If a callback is passed the query is executed. - -```js -mquery().findOne() -mquery().findOne(match) -mquery().findOne(callback) -mquery().findOne(match, function (err, doc) { - if (doc) { - // the document may not be found - console.log(doc); - } -}) -``` - -### count() - -Declares this query a _count_ query. Optionally pass a match clause and / or callback. If a callback is passed the query is executed. - -```js -mquery().count() -mquery().count(match) -mquery().count(callback) -mquery().count(match, function (err, number){ - console.log('we found %d matching documents', number); -}) -``` - -### remove() - -Declares this query a _remove_ query. Optionally pass a match clause and / or callback. If a callback is passed the query is executed. - -```js -mquery().remove() -mquery().remove(match) -mquery().remove(callback) -mquery().remove(match, function (err){}) -``` - -### update() - -Declares this query an _update_ query. Optionally pass an update document, match clause, options or callback. If a callback is passed, the query is executed. To force execution without passing a callback, run `update(true)`. - -```js -mquery().update() -mquery().update(match, updateDocument) -mquery().update(match, updateDocument, options) - -// the following all execute the command -mquery().update(callback) -mquery().update({$set: updateDocument, callback) -mquery().update(match, updateDocument, callback) -mquery().update(match, updateDocument, options, function (err, result){}) -mquery().update(true) // executes (unsafe write) -``` - -##### the update document - -All paths passed that are not `$atomic` operations will become `$set` ops. For example: - -```js -mquery(collection).where({ _id: id }).update({ title: 'words' }, callback) -``` - -becomes - -```js -collection.update({ _id: id }, { $set: { title: 'words' }}, callback) -``` - -This behavior can be overridden using the `overwrite` option (see below). - -##### options - -Options are passed to the `setOptions()` method. - -- overwrite - -Passing an empty object `{ }` as the update document will result in a no-op unless the `overwrite` option is passed. Without the `overwrite` option, the update operation will be ignored and the callback executed without sending the command to MongoDB to prevent accidently overwritting documents in the collection. - -```js -var q = mquery(collection).where({ _id: id }).setOptions({ overwrite: true }); -q.update({ }, callback); // overwrite with an empty doc -``` - -The `overwrite` option isn't just for empty objects, it also provides a means to override the default `$set` conversion and send the update document as is. - -```js -// create a base query -var base = mquery({ _id: 108 }).collection(collection).toConstructor(); - -base().findOne(function (err, doc) { - console.log(doc); // { _id: 108, name: 'cajon' }) - - base().setOptions({ overwrite: true }).update({ changed: true }, function (err) { - base.findOne(function (err, doc) { - console.log(doc); // { _id: 108, changed: true }) - the doc was overwritten - }); - }); -}) -``` - -- multi - -Updates only modify a single document by default. To update multiple documents, set the `multi` option to `true`. - -```js -mquery() - .collection(coll) - .update({ name: /^match/ }, { $addToSet: { arr: 4 }}, { multi: true }, callback) - -// another way of doing it -mquery({ name: /^match/ }) - .collection(coll) - .setOptions({ multi: true }) - .update({ $addToSet: { arr: 4 }}, callback) - -// update multiple documents with an empty doc -var q = mquery(collection).where({ name: /^match/ }); -q.setOptions({ multi: true, overwrite: true }) -q.update({ }); -q.update(function (err, result) { - console.log(arguments); -}); -``` - -### findOneAndUpdate() - -Declares this query a _findAndModify_ with update query. Optionally pass a match clause, update document, options, or callback. If a callback is passed, the query is executed. - -When executed, the first matching document (if found) is modified according to the update document and passed back to the callback. - -##### options - -Options are passed to the `setOptions()` method. - -- `new`: boolean - true to return the modified document rather than the original. defaults to true -- `upsert`: boolean - creates the object if it doesn't exist. defaults to false -- `sort`: if multiple docs are found by the match condition, sets the sort order to choose which doc to update - -```js -query.findOneAndUpdate() -query.findOneAndUpdate(updateDocument) -query.findOneAndUpdate(match, updateDocument) -query.findOneAndUpdate(match, updateDocument, options) - -// the following all execute the command -query.findOneAndUpdate(callback) -query.findOneAndUpdate(updateDocument, callback) -query.findOneAndUpdate(match, updateDocument, callback) -query.findOneAndUpdate(match, updateDocument, options, function (err, doc) { - if (doc) { - // the document may not be found - console.log(doc); - } -}) - ``` - -### findOneAndRemove() - -Declares this query a _findAndModify_ with remove query. Alias of findOneAndDelete. -Optionally pass a match clause, options, or callback. If a callback is passed, the query is executed. - -When executed, the first matching document (if found) is modified according to the update document, removed from the collection and passed to the callback. - -##### options - -Options are passed to the `setOptions()` method. - -- `sort`: if multiple docs are found by the condition, sets the sort order to choose which doc to modify and remove - -```js -A.where().findOneAndDelete() -A.where().findOneAndRemove() -A.where().findOneAndRemove(match) -A.where().findOneAndRemove(match, options) - -// the following all execute the command -A.where().findOneAndRemove(callback) -A.where().findOneAndRemove(match, callback) -A.where().findOneAndRemove(match, options, function (err, doc) { - if (doc) { - // the document may not be found - console.log(doc); - } -}) - ``` - -### distinct() - -Declares this query a _distinct_ query. Optionally pass the distinct field, a match clause or callback. If a callback is passed the query is executed. - -```js -mquery().distinct() -mquery().distinct(match) -mquery().distinct(match, field) -mquery().distinct(field) - -// the following all execute the command -mquery().distinct(callback) -mquery().distinct(field, callback) -mquery().distinct(match, callback) -mquery().distinct(match, field, function (err, result) { - console.log(result); -}) -``` - -### exec() - -Executes the query. - -```js -mquery().findOne().where('route').intersects(polygon).exec(function (err, docs){}) -``` - -### stream() - -Executes the query and returns a stream. - -```js -var stream = mquery().find().stream(options); -stream.on('data', cb); -stream.on('close', fn); -``` - -Note: this only works with `find()` operations. - -Note: returns the stream object directly from the node-mongodb-native driver. (currently streams1 type stream). Any options will be passed along to the [driver method](http://mongodb.github.io/node-mongodb-native/api-generated/cursor.html#stream). - -------------- - -### all() - -Specifies an `$all` query condition - -```js -mquery().where('permission').all(['read', 'write']) -``` - -[MongoDB documentation](http://docs.mongodb.org/manual/reference/operator/all/) - -### and() - -Specifies arguments for an `$and` condition - -```js -mquery().and([{ color: 'green' }, { status: 'ok' }]) -``` - -[MongoDB documentation](http://docs.mongodb.org/manual/reference/operator/and/) - -### box() - -Specifies a `$box` condition - -```js -var lowerLeft = [40.73083, -73.99756] -var upperRight= [40.741404, -73.988135] - -mquery().where('location').within().box(lowerLeft, upperRight) -``` - -[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/box/) - -### circle() - -Specifies a `$center` or `$centerSphere` condition. - -```js -var area = { center: [50, 50], radius: 10, unique: true } -query.where('loc').within().circle(area) -query.circle('loc', area); - -// for spherical calculations -var area = { center: [50, 50], radius: 10, unique: true, spherical: true } -query.where('loc').within().circle(area) -query.circle('loc', area); -``` - -- [MongoDB Documentation - center](http://docs.mongodb.org/manual/reference/operator/center/) -- [MongoDB Documentation - centerSphere](http://docs.mongodb.org/manual/reference/operator/centerSphere/) - -### elemMatch() - -Specifies an `$elemMatch` condition - -```js -query.where('comment').elemMatch({ author: 'autobot', votes: {$gte: 5}}) - -query.elemMatch('comment', function (elem) { - elem.where('author').equals('autobot'); - elem.where('votes').gte(5); -}) -``` - -[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/elemMatch/) - -### equals() - -Specifies the complementary comparison value for the path specified with `where()`. - -```js -mquery().where('age').equals(49); - -// is the same as - -mquery().where({ 'age': 49 }); -``` - -### exists() - -Specifies an `$exists` condition - -```js -// { name: { $exists: true }} -mquery().where('name').exists() -mquery().where('name').exists(true) -mquery().exists('name') - -// { name: { $exists: false }} -mquery().where('name').exists(false); -mquery().exists('name', false); -``` - -[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/exists/) - -### geometry() - -Specifies a `$geometry` condition - -```js -var polyA = [[[ 10, 20 ], [ 10, 40 ], [ 30, 40 ], [ 30, 20 ]]] -query.where('loc').within().geometry({ type: 'Polygon', coordinates: polyA }) - -// or -var polyB = [[ 0, 0 ], [ 1, 1 ]] -query.where('loc').within().geometry({ type: 'LineString', coordinates: polyB }) - -// or -var polyC = [ 0, 0 ] -query.where('loc').within().geometry({ type: 'Point', coordinates: polyC }) - -// or -query.where('loc').intersects().geometry({ type: 'Point', coordinates: polyC }) - -// or -query.where('loc').near().geometry({ type: 'Point', coordinates: [3,5] }) -``` - -`geometry()` **must** come after `intersects()`, `within()`, or `near()`. - -The `object` argument must contain `type` and `coordinates` properties. - -- type `String` -- coordinates `Array` - -[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/geometry/) - -### gt() - -Specifies a `$gt` query condition. - -```js -mquery().where('clicks').gt(999) -``` - -[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/gt/) - -### gte() - -Specifies a `$gte` query condition. - -[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/gte/) - -```js -mquery().where('clicks').gte(1000) -``` - -### in() - -Specifies an `$in` query condition. - -```js -mquery().where('author_id').in([3, 48901, 761]) -``` - -[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/in/) - -### intersects() - -Declares an `$geoIntersects` query for `geometry()`. - -```js -query.where('path').intersects().geometry({ - type: 'LineString' - , coordinates: [[180.0, 11.0], [180, 9.0]] -}) - -// geometry arguments are supported -query.where('path').intersects({ - type: 'LineString' - , coordinates: [[180.0, 11.0], [180, 9.0]] -}) -``` - -**Must** be used after `where()`. - -[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/geoIntersects/) - -### lt() - -Specifies a `$lt` query condition. - -```js -mquery().where('clicks').lt(50) -``` - -[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/lt/) - -### lte() - -Specifies a `$lte` query condition. - -```js -mquery().where('clicks').lte(49) -``` - -[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/lte/) - -### maxDistance() - -Specifies a `$maxDistance` query condition. - -```js -mquery().where('location').near({ center: [139, 74.3] }).maxDistance(5) -``` - -[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/maxDistance/) - -### mod() - -Specifies a `$mod` condition - -```js -mquery().where('count').mod(2, 0) -``` - -[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/mod/) - -### ne() - -Specifies a `$ne` query condition. - -```js -mquery().where('status').ne('ok') -``` - -[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/ne/) - -### nin() - -Specifies an `$nin` query condition. - -```js -mquery().where('author_id').nin([3, 48901, 761]) -``` - -[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/nin/) - -### nor() - -Specifies arguments for an `$nor` condition. - -```js -mquery().nor([{ color: 'green' }, { status: 'ok' }]) -``` - -[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/nor/) - -### near() - -Specifies arguments for a `$near` or `$nearSphere` condition. - -These operators return documents sorted by distance. - -#### Example - -```js -query.where('loc').near({ center: [10, 10] }); -query.where('loc').near({ center: [10, 10], maxDistance: 5 }); -query.near('loc', { center: [10, 10], maxDistance: 5 }); - -// GeoJSON -query.where('loc').near({ center: { type: 'Point', coordinates: [10, 10] }}); -query.where('loc').near({ center: { type: 'Point', coordinates: [10, 10] }, maxDistance: 5, spherical: true }); -query.where('loc').near().geometry({ type: 'Point', coordinates: [10, 10] }); - -// For a $nearSphere condition, pass the `spherical` option. -query.near({ center: [10, 10], maxDistance: 5, spherical: true }); -``` - -[MongoDB Documentation](http://www.mongodb.org/display/DOCS/Geospatial+Indexing) - -### or() - -Specifies arguments for an `$or` condition. - -```js -mquery().or([{ color: 'red' }, { status: 'emergency' }]) -``` - -[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/or/) - -### polygon() - -Specifies a `$polygon` condition - -```js -mquery().where('loc').within().polygon([10,20], [13, 25], [7,15]) -mquery().polygon('loc', [10,20], [13, 25], [7,15]) -``` - -[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/polygon/) - -### regex() - -Specifies a `$regex` query condition. - -```js -mquery().where('name').regex(/^sixstepsrecords/) -``` - -[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/regex/) - -### select() - -Specifies which document fields to include or exclude - -```js -// 1 means include, 0 means exclude -mquery().select({ name: 1, address: 1, _id: 0 }) - -// or - -mquery().select('name address -_id') -``` - -##### String syntax - -When passing a string, prefixing a path with `-` will flag that path as excluded. When a path does not have the `-` prefix, it is included. - -```js -// include a and b, exclude c -query.select('a b -c'); - -// or you may use object notation, useful when -// you have keys already prefixed with a "-" -query.select({a: 1, b: 1, c: 0}); -``` - -_Cannot be used with `distinct()`._ - -### selected() - -Determines if the query has selected any fields. - -```js -var query = mquery(); -query.selected() // false -query.select('-name'); -query.selected() // true -``` - -### selectedInclusively() - -Determines if the query has selected any fields inclusively. - -```js -var query = mquery().select('name'); -query.selectedInclusively() // true - -var query = mquery(); -query.selected() // false -query.select('-name'); -query.selectedInclusively() // false -query.selectedExclusively() // true -``` - -### selectedExclusively() - -Determines if the query has selected any fields exclusively. - -```js -var query = mquery().select('-name'); -query.selectedExclusively() // true - -var query = mquery(); -query.selected() // false -query.select('name'); -query.selectedExclusively() // false -query.selectedInclusively() // true -``` - -### size() - -Specifies a `$size` query condition. - -```js -mquery().where('someArray').size(6) -``` - -[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/size/) - -### slice() - -Specifies a `$slice` projection for a `path` - -```js -mquery().where('comments').slice(5) -mquery().where('comments').slice(-5) -mquery().where('comments').slice([-10, 5]) -``` - -[MongoDB Documentation](http://docs.mongodb.org/manual/reference/projection/slice/) - -### within() - -Sets a `$geoWithin` or `$within` argument for geo-spatial queries. - -```js -mquery().within().box() -mquery().within().circle() -mquery().within().geometry() - -mquery().where('loc').within({ center: [50,50], radius: 10, unique: true, spherical: true }); -mquery().where('loc').within({ box: [[40.73, -73.9], [40.7, -73.988]] }); -mquery().where('loc').within({ polygon: [[],[],[],[]] }); - -mquery().where('loc').within([], [], []) // polygon -mquery().where('loc').within([], []) // box -mquery().where('loc').within({ type: 'LineString', coordinates: [...] }); // geometry -``` - -As of mquery 2.0, `$geoWithin` is used by default. This impacts you if running MongoDB < 2.4. To alter this behavior, see [mquery.use$geoWithin](#mqueryusegeowithin). - -**Must** be used after `where()`. - -[MongoDB Documentation](http://docs.mongodb.org/manual/reference/operator/geoWithin/) - -### where() - -Specifies a `path` for use with chaining - -```js -// instead of writing: -mquery().find({age: {$gte: 21, $lte: 65}}); - -// we can instead write: -mquery().where('age').gte(21).lte(65); - -// passing query conditions is permitted too -mquery().find().where({ name: 'vonderful' }) - -// chaining -mquery() -.where('age').gte(21).lte(65) -.where({ 'name': /^vonderful/i }) -.where('friends').slice(10) -.exec(callback) -``` - -### $where() - -Specifies a `$where` condition. - -Use `$where` when you need to select documents using a JavaScript expression. - -```js -query.$where('this.comments.length > 10 || this.name.length > 5').exec(callback) - -query.$where(function () { - return this.comments.length > 10 || this.name.length > 5; -}) -``` - -Only use `$where` when you have a condition that cannot be met using other MongoDB operators like `$lt`. Be sure to read about all of [its caveats](http://docs.mongodb.org/manual/reference/operator/where/) before using. - ------------ - -### batchSize() - -Specifies the batchSize option. - -```js -query.batchSize(100) -``` - -_Cannot be used with `distinct()`._ - -[MongoDB documentation](http://docs.mongodb.org/manual/reference/method/cursor.batchSize/) - -### collation() - -Specifies the collation option. - -```js -query.collation({ locale: "en_US", strength: 1 }) -``` - -[MongoDB documentation](https://docs.mongodb.com/manual/reference/method/cursor.collation/#cursor.collation) - -### comment() - -Specifies the comment option. - -```js -query.comment('login query'); -``` - -_Cannot be used with `distinct()`._ - -[MongoDB documentation](http://docs.mongodb.org/manual/reference/operator/) - -### hint() - -Sets query hints. - -```js -mquery().hint({ indexA: 1, indexB: -1 }) -``` - -_Cannot be used with `distinct()`._ - -[MongoDB documentation](http://docs.mongodb.org/manual/reference/operator/hint/) - -### j() - -Requests acknowledgement that this operation has been persisted to MongoDB's on-disk journal. - -This option is only valid for operations that write to the database: - -- `deleteOne()` -- `deleteMany()` -- `findOneAndDelete()` -- `findOneAndUpdate()` -- `remove()` -- `update()` -- `updateOne()` -- `updateMany()` - -Defaults to the `j` value if it is specified in [writeConcern](#writeconcern) - -```js -mquery().j(true); -``` - -### limit() - -Specifies the limit option. - -```js -query.limit(20) -``` - -_Cannot be used with `distinct()`._ - -[MongoDB documentation](http://docs.mongodb.org/manual/reference/method/cursor.limit/) - -### maxScan() - -Specifies the maxScan option. - -```js -query.maxScan(100) -``` - -_Cannot be used with `distinct()`._ - -[MongoDB documentation](http://docs.mongodb.org/manual/reference/operator/maxScan/) - -### maxTime() - -Specifies the maxTimeMS option. - -```js -query.maxTime(100) -query.maxTimeMS(100) -``` - -[MongoDB documentation](http://docs.mongodb.org/manual/reference/method/cursor.maxTimeMS/) - - -### skip() - -Specifies the skip option. - -```js -query.skip(100).limit(20) -``` - -_Cannot be used with `distinct()`._ - -[MongoDB documentation](http://docs.mongodb.org/manual/reference/method/cursor.skip/) - -### sort() - -Sets the query sort order. - -If an object is passed, key values allowed are `asc`, `desc`, `ascending`, `descending`, `1`, and `-1`. - -If a string is passed, it must be a space delimited list of path names. The sort order of each path is ascending unless the path name is prefixed with `-` which will be treated as descending. - -```js -// these are equivalent -query.sort({ field: 'asc', test: -1 }); -query.sort('field -test'); -``` - -_Cannot be used with `distinct()`._ - -[MongoDB documentation](http://docs.mongodb.org/manual/reference/method/cursor.sort/) - -### read() - -Sets the readPreference option for the query. - -```js -mquery().read('primary') -mquery().read('p') // same as primary - -mquery().read('primaryPreferred') -mquery().read('pp') // same as primaryPreferred - -mquery().read('secondary') -mquery().read('s') // same as secondary - -mquery().read('secondaryPreferred') -mquery().read('sp') // same as secondaryPreferred - -mquery().read('nearest') -mquery().read('n') // same as nearest - -mquery().setReadPreference('primary') // alias of .read() -``` - -##### Preferences: - -- `primary` - (default) Read from primary only. Operations will produce an error if primary is unavailable. Cannot be combined with tags. -- `secondary` - Read from secondary if available, otherwise error. -- `primaryPreferred` - Read from primary if available, otherwise a secondary. -- `secondaryPreferred` - Read from a secondary if available, otherwise read from the primary. -- `nearest` - All operations read from among the nearest candidates, but unlike other modes, this option will include both the primary and all secondaries in the random selection. - -Aliases - -- `p` primary -- `pp` primaryPreferred -- `s` secondary -- `sp` secondaryPreferred -- `n` nearest - -##### Preference Tags: - -To keep the separation of concerns between `mquery` and your driver -clean, `mquery#read()` no longer handles specifying a second `tags` argument as of version 0.5. -If you need to specify tags, pass any non-string argument as the first argument. -`mquery` will pass this argument untouched to your collections methods later. -For example: - -```js -// example of specifying tags using the Node.js driver -var ReadPref = require('mongodb').ReadPreference; -var preference = new ReadPref('secondary', [{ dc:'sf', s: 1 },{ dc:'ma', s: 2 }]); -mquery(..).read(preference).exec(); -``` - -Read more about how to use read preferences [here](http://docs.mongodb.org/manual/applications/replication/#read-preference) and [here](http://mongodb.github.com/node-mongodb-native/driver-articles/anintroductionto1_1and2_2.html#read-preferences). - - -### readConcern() - -Sets the readConcern option for the query. - -```js -// local -mquery().readConcern('local') -mquery().readConcern('l') -mquery().r('l') - -// available -mquery().readConcern('available') -mquery().readConcern('a') -mquery().r('a') - -// majority -mquery().readConcern('majority') -mquery().readConcern('m') -mquery().r('m') - -// linearizable -mquery().readConcern('linearizable') -mquery().readConcern('lz') -mquery().r('lz') - -// snapshot -mquery().readConcern('snapshot') -mquery().readConcern('s') -mquery().r('s') -``` - -##### Read Concern Level: - -- `local` - The query returns from the instance with no guarantee guarantee that the data has been written to a majority of the replica set members (i.e. may be rolled back). (MongoDB 3.2+) -- `available` - The query returns from the instance with no guarantee guarantee that the data has been written to a majority of the replica set members (i.e. may be rolled back). (MongoDB 3.6+) -- `majority` - The query returns the data that has been acknowledged by a majority of the replica set members. The documents returned by the read operation are durable, even in the event of failure. (MongoDB 3.2+) -- `linearizable` - The query returns data that reflects all successful majority-acknowledged writes that completed prior to the start of the read operation. The query may wait for concurrently executing writes to propagate to a majority of replica set members before returning results. (MongoDB 3.4+) -- `snapshot` - Only available for operations within multi-document transactions. Upon transaction commit with write concern "majority", the transaction operations are guaranteed to have read from a snapshot of majority-committed data. (MongoDB 4.0+) - -Aliases - -- `l` local -- `a` available -- `m` majority -- `lz` linearizable -- `s` snapshot - -Read more about how to use read concern [here](https://docs.mongodb.com/manual/reference/read-concern/). - -### writeConcern() - -Sets the writeConcern option for the query. - -This option is only valid for operations that write to the database: - -- `deleteOne()` -- `deleteMany()` -- `findOneAndDelete()` -- `findOneAndUpdate()` -- `remove()` -- `update()` -- `updateOne()` -- `updateMany()` - -```js -mquery().writeConcern(0) -mquery().writeConcern(1) -mquery().writeConcern({ w: 1, j: true, wtimeout: 2000 }) -mquery().writeConcern('majority') -mquery().writeConcern('m') // same as majority -mquery().writeConcern('tagSetName') // if the tag set is 'm', use .writeConcern({ w: 'm' }) instead -mquery().w(1) // w is alias of writeConcern -``` - -##### Write Concern: - -writeConcern({ w: ``, j: ``, wtimeout: `` }`) - -- the w option to request acknowledgement that the write operation has propagated to a specified number of mongod instances or to mongod instances with specified tags -- the j option to request acknowledgement that the write operation has been written to the journal -- the wtimeout option to specify a time limit to prevent write operations from blocking indefinitely - -Can be break down to use the following syntax: - -mquery().w(``).j(``).wtimeout(``) - -Read more about how to use write concern [here](https://docs.mongodb.com/manual/reference/write-concern/) - -### slaveOk() - -Sets the slaveOk option. `true` allows reading from secondaries. - -**deprecated** use [read()](#read) preferences instead if on mongodb >= 2.2 - -```js -query.slaveOk() // true -query.slaveOk(true) -query.slaveOk(false) -``` - -[MongoDB documentation](http://docs.mongodb.org/manual/reference/method/rs.slaveOk/) - -### snapshot() - -Specifies this query as a snapshot query. - -```js -mquery().snapshot() // true -mquery().snapshot(true) -mquery().snapshot(false) -``` - -_Cannot be used with `distinct()`._ - -[MongoDB documentation](http://docs.mongodb.org/manual/reference/operator/snapshot/) - -### tailable() - -Sets tailable option. - -```js -mquery().tailable() <== true -mquery().tailable(true) -mquery().tailable(false) -``` - -_Cannot be used with `distinct()`._ - -[MongoDB Documentation](http://docs.mongodb.org/manual/tutorial/create-tailable-cursor/) - -### wtimeout() - -Specifies a time limit, in milliseconds, for the write concern. If `w > 1`, it is maximum amount of time to -wait for this write to propagate through the replica set before this operation fails. The default is `0`, which means no timeout. - -This option is only valid for operations that write to the database: - -- `deleteOne()` -- `deleteMany()` -- `findOneAndDelete()` -- `findOneAndUpdate()` -- `remove()` -- `update()` -- `updateOne()` -- `updateMany()` - -Defaults to `wtimeout` value if it is specified in [writeConcern](#writeconcern) - -```js -mquery().wtimeout(2000) -mquery().wTimeout(2000) -``` - -## Helpers - -### collection() - -Sets the querys collection. - -```js -mquery().collection(aCollection) -``` - -### then() - -Executes the query and returns a promise which will be resolved with the query results or rejected if the query responds with an error. - -```js -mquery().find(..).then(success, error); -``` - -This is very useful when combined with [co](https://github.com/visionmedia/co) or [koa](https://github.com/koajs/koa), which automatically resolve promise-like objects for you. - -```js -co(function*(){ - var doc = yield mquery().findOne({ _id: 499 }); - console.log(doc); // { _id: 499, name: 'amazing', .. } -})(); -``` - -_NOTE_: -The returned promise is a [bluebird](https://github.com/petkaantonov/bluebird/) promise but this is customizable. If you want to -use your favorite promise library, simply set `mquery.Promise = YourPromiseConstructor`. -Your `Promise` must be [promises A+](http://promisesaplus.com/) compliant. - -### thunk() - -Returns a thunk which when called runs the query's `exec` method passing the results to the callback. - -```js -var thunk = mquery(collection).find({..}).thunk(); - -thunk(function(err, results) { - -}) -``` - -### merge(object) - -Merges other mquery or match condition objects into this one. When an mquery instance is passed, its match conditions, field selection and options are merged. - -```js -var drum = mquery({ type: 'drum' }).collection(instruments); -var redDrum = mquery({ color: 'red' }).merge(drum); -redDrum.count(function (err, n) { - console.log('there are %d red drums', n); -}) -``` - -Internally uses `mquery.canMerge` to determine validity. - -### setOptions(options) - -Sets query options. - -```js -mquery().setOptions({ collection: coll, limit: 20 }) -``` - -##### options - -- [tailable](#tailable) * -- [sort](#sort) * -- [limit](#limit) * -- [skip](#skip) * -- [maxScan](#maxscan) * -- [maxTime](#maxtime) * -- [batchSize](#batchSize) * -- [comment](#comment) * -- [snapshot](#snapshot) * -- [hint](#hint) * -- [slaveOk](#slaveOk) * -- [safe](http://docs.mongodb.org/manual/reference/write-concern/): Boolean - passed through to the collection. Setting to `true` is equivalent to `{ w: 1 }` -- [collection](#collection): the collection to query against - -_* denotes a query helper method is also available_ - -### setTraceFunction(func) - -Set a function to trace this query. Useful for profiling or logging. - -```js -function traceFunction (method, queryInfo, query) { - console.log('starting ' + method + ' query'); - - return function (err, result, millis) { - console.log('finished ' + method + ' query in ' + millis + 'ms'); - }; -} - -mquery().setTraceFunction(traceFunction).findOne({name: 'Joe'}, cb); -``` - -The trace function is passed (method, queryInfo, query) - -- method is the name of the method being called (e.g. findOne) -- queryInfo contains information about the query: - - conditions: query conditions/criteria - - options: options such as sort, fields, etc - - doc: document being updated -- query is the query object - -The trace function should return a callback function which accepts: -- err: error, if any -- result: result, if any -- millis: time spent waiting for query result - -NOTE: stream requests are not traced. - -### mquery.setGlobalTraceFunction(func) - -Similar to `setTraceFunction()` but automatically applied to all queries. - -```js -mquery.setTraceFunction(traceFunction); -``` - -### mquery.canMerge(conditions) - -Determines if `conditions` can be merged using `mquery().merge()`. - -```js -var query = mquery({ type: 'drum' }); -var okToMerge = mquery.canMerge(anObject) -if (okToMerge) { - query.merge(anObject); -} -``` - -## mquery.use$geoWithin - -MongoDB 2.4 introduced the `$geoWithin` operator which replaces and is 100% backward compatible with `$within`. As of mquery 0.2, we default to using `$geoWithin` for all `within()` calls. - -If you are running MongoDB < 2.4 this will be problematic. To force `mquery` to be backward compatible and always use `$within`, set the `mquery.use$geoWithin` flag to `false`. - -```js -mquery.use$geoWithin = false; -``` - -## Custom Base Queries - -Often times we want custom base queries that encapsulate predefined criteria. With `mquery` this is easy. First create the query you want to reuse and call its `toConstructor()` method which returns a new subclass of `mquery` that retains all options and criteria of the original. - -```js -var greatMovies = mquery(movieCollection).where('rating').gte(4.5).toConstructor(); - -// use it! -greatMovies().count(function (err, n) { - console.log('There are %d great movies', n); -}); - -greatMovies().where({ name: /^Life/ }).select('name').find(function (err, docs) { - console.log(docs); -}); -``` - -## Validation - -Method and options combinations are checked for validity at runtime to prevent creation of invalid query constructs. For example, a `distinct` query does not support specifying options like `hint` or field selection. In this case an error will be thrown so you can catch these mistakes in development. - -## Debug support - -Debug mode is provided through the use of the [debug](https://github.com/visionmedia/debug) module. To enable: - - DEBUG=mquery node yourprogram.js - -Read the debug module documentation for more details. - -## General compatibility - -#### ObjectIds - -`mquery` clones query arguments before passing them to a `collection` method for execution. -This prevents accidental side-affects to the objects you pass. -To clone `ObjectIds` we need to make some assumptions. - -First, to check if an object is an `ObjectId`, we check its constructors name. If it matches either -`ObjectId` or `ObjectID` we clone it. - -To clone `ObjectIds`, we call its optional `clone` method. If a `clone` method does not exist, we fall -back to calling `new obj.constructor(obj.id)`. We assume, for compatibility with the -Node.js driver, that the `ObjectId` instance has a public `id` property and that -when creating an `ObjectId` instance we can pass that `id` as an argument. - -#### Read Preferences - -`mquery` supports specifying [Read Preferences]() to control from which MongoDB node your query will read. -The Read Preferences spec also support specifying tags. To pass tags, some -drivers (Node.js driver) require passing a special constructor that handles both the read preference and its tags. -If you need to specify tags, pass an instance of your drivers ReadPreference constructor or roll your own. `mquery` will store whatever you provide and pass later to your collection during execution. - -## Future goals - - - mongo shell compatibility - - browser compatibility - -## Installation - - $ npm install mquery - -## License - -[MIT](https://github.com/aheckmann/mquery/blob/master/LICENSE) - diff --git a/node_modules/mquery/lib/collection/collection.js b/node_modules/mquery/lib/collection/collection.js deleted file mode 100644 index 0f39c76..0000000 --- a/node_modules/mquery/lib/collection/collection.js +++ /dev/null @@ -1,46 +0,0 @@ -'use strict'; - -/** - * methods a collection must implement - */ - -var methods = [ - 'find', - 'findOne', - 'update', - 'updateMany', - 'updateOne', - 'replaceOne', - 'remove', - 'count', - 'distinct', - 'findAndModify', - 'aggregate', - 'findStream', - 'deleteOne', - 'deleteMany' -]; - -/** - * Collection base class from which implementations inherit - */ - -function Collection() {} - -for (var i = 0, len = methods.length; i < len; ++i) { - var method = methods[i]; - Collection.prototype[method] = notImplemented(method); -} - -module.exports = exports = Collection; -Collection.methods = methods; - -/** - * creates a function which throws an implementation error - */ - -function notImplemented(method) { - return function() { - throw new Error('collection.' + method + ' not implemented'); - }; -} diff --git a/node_modules/mquery/lib/collection/index.js b/node_modules/mquery/lib/collection/index.js deleted file mode 100644 index 1992e20..0000000 --- a/node_modules/mquery/lib/collection/index.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict'; - -var env = require('../env'); - -if ('unknown' == env.type) { - throw new Error('Unknown environment'); -} - -module.exports = - env.isNode ? require('./node') : - env.isMongo ? require('./collection') : - require('./collection'); - diff --git a/node_modules/mquery/lib/collection/node.js b/node_modules/mquery/lib/collection/node.js deleted file mode 100644 index cc07d60..0000000 --- a/node_modules/mquery/lib/collection/node.js +++ /dev/null @@ -1,151 +0,0 @@ -'use strict'; - -/** - * Module dependencies - */ - -var Collection = require('./collection'); -var utils = require('../utils'); - -function NodeCollection(col) { - this.collection = col; - this.collectionName = col.collectionName; -} - -/** - * inherit from collection base class - */ - -utils.inherits(NodeCollection, Collection); - -/** - * find(match, options, function(err, docs)) - */ - -NodeCollection.prototype.find = function(match, options, cb) { - this.collection.find(match, options, function(err, cursor) { - if (err) return cb(err); - - try { - cursor.toArray(cb); - } catch (error) { - cb(error); - } - }); -}; - -/** - * findOne(match, options, function(err, doc)) - */ - -NodeCollection.prototype.findOne = function(match, options, cb) { - this.collection.findOne(match, options, cb); -}; - -/** - * count(match, options, function(err, count)) - */ - -NodeCollection.prototype.count = function(match, options, cb) { - this.collection.count(match, options, cb); -}; - -/** - * distinct(prop, match, options, function(err, count)) - */ - -NodeCollection.prototype.distinct = function(prop, match, options, cb) { - this.collection.distinct(prop, match, options, cb); -}; - -/** - * update(match, update, options, function(err[, result])) - */ - -NodeCollection.prototype.update = function(match, update, options, cb) { - this.collection.update(match, update, options, cb); -}; - -/** - * update(match, update, options, function(err[, result])) - */ - -NodeCollection.prototype.updateMany = function(match, update, options, cb) { - this.collection.updateMany(match, update, options, cb); -}; - -/** - * update(match, update, options, function(err[, result])) - */ - -NodeCollection.prototype.updateOne = function(match, update, options, cb) { - this.collection.updateOne(match, update, options, cb); -}; - -/** - * replaceOne(match, update, options, function(err[, result])) - */ - -NodeCollection.prototype.replaceOne = function(match, update, options, cb) { - this.collection.replaceOne(match, update, options, cb); -}; - -/** - * deleteOne(match, options, function(err[, result]) - */ - -NodeCollection.prototype.deleteOne = function(match, options, cb) { - this.collection.deleteOne(match, options, cb); -}; - -/** - * deleteMany(match, options, function(err[, result]) - */ - -NodeCollection.prototype.deleteMany = function(match, options, cb) { - this.collection.deleteMany(match, options, cb); -}; - -/** - * remove(match, options, function(err[, result]) - */ - -NodeCollection.prototype.remove = function(match, options, cb) { - this.collection.remove(match, options, cb); -}; - -/** - * findAndModify(match, update, options, function(err, doc)) - */ - -NodeCollection.prototype.findAndModify = function(match, update, options, cb) { - var sort = Array.isArray(options.sort) ? options.sort : []; - this.collection.findAndModify(match, sort, update, options, cb); -}; - -/** - * var stream = findStream(match, findOptions, streamOptions) - */ - -NodeCollection.prototype.findStream = function(match, findOptions, streamOptions) { - return this.collection.find(match, findOptions).stream(streamOptions); -}; - -/** - * var cursor = findCursor(match, findOptions) - */ - -NodeCollection.prototype.findCursor = function(match, findOptions) { - return this.collection.find(match, findOptions); -}; - -/** - * aggregation(operators..., function(err, doc)) - * TODO - */ - -/** - * Expose - */ - -module.exports = exports = NodeCollection; diff --git a/node_modules/mquery/lib/env.js b/node_modules/mquery/lib/env.js deleted file mode 100644 index d3d225b..0000000 --- a/node_modules/mquery/lib/env.js +++ /dev/null @@ -1,22 +0,0 @@ -'use strict'; - -exports.isNode = 'undefined' != typeof process - && 'object' == typeof module - && 'object' == typeof global - && 'function' == typeof Buffer - && process.argv; - -exports.isMongo = !exports.isNode - && 'function' == typeof printjson - && 'function' == typeof ObjectId - && 'function' == typeof rs - && 'function' == typeof sh; - -exports.isBrowser = !exports.isNode - && !exports.isMongo - && 'undefined' != typeof window; - -exports.type = exports.isNode ? 'node' - : exports.isMongo ? 'mongo' - : exports.isBrowser ? 'browser' - : 'unknown'; diff --git a/node_modules/mquery/lib/mquery.js b/node_modules/mquery/lib/mquery.js deleted file mode 100644 index 8fdd9e1..0000000 --- a/node_modules/mquery/lib/mquery.js +++ /dev/null @@ -1,3252 +0,0 @@ -'use strict'; - -/** - * Dependencies - */ - -var slice = require('sliced'); -var assert = require('assert'); -var util = require('util'); -var utils = require('./utils'); -var debug = require('debug')('mquery'); - -/* global Map */ - -/** - * Query constructor used for building queries. - * - * ####Example: - * - * var query = new Query({ name: 'mquery' }); - * query.setOptions({ collection: moduleCollection }) - * query.where('age').gte(21).exec(callback); - * - * @param {Object} [criteria] - * @param {Object} [options] - * @api public - */ - -function Query(criteria, options) { - if (!(this instanceof Query)) - return new Query(criteria, options); - - var proto = this.constructor.prototype; - - this.op = proto.op || undefined; - - this.options = Object.assign({}, proto.options); - - this._conditions = proto._conditions - ? utils.clone(proto._conditions) - : {}; - - this._fields = proto._fields - ? utils.clone(proto._fields) - : undefined; - - this._update = proto._update - ? utils.clone(proto._update) - : undefined; - - this._path = proto._path || undefined; - this._distinct = proto._distinct || undefined; - this._collection = proto._collection || undefined; - this._traceFunction = proto._traceFunction || undefined; - - if (options) { - this.setOptions(options); - } - - if (criteria) { - if (criteria.find && criteria.remove && criteria.update) { - // quack quack! - this.collection(criteria); - } else { - this.find(criteria); - } - } -} - -/** - * This is a parameter that the user can set which determines if mquery - * uses $within or $geoWithin for queries. It defaults to true which - * means $geoWithin will be used. If using MongoDB < 2.4 you should - * set this to false. - * - * @api public - * @property use$geoWithin - */ - -var $withinCmd = '$geoWithin'; -Object.defineProperty(Query, 'use$geoWithin', { - get: function( ) { return $withinCmd == '$geoWithin'; }, - set: function(v) { - if (true === v) { - // mongodb >= 2.4 - $withinCmd = '$geoWithin'; - } else { - $withinCmd = '$within'; - } - } -}); - -/** - * Converts this query to a constructor function with all arguments and options retained. - * - * ####Example - * - * // Create a query that will read documents with a "video" category from - * // `aCollection` on the primary node in the replica-set unless it is down, - * // in which case we'll read from a secondary node. - * var query = mquery({ category: 'video' }) - * query.setOptions({ collection: aCollection, read: 'primaryPreferred' }); - * - * // create a constructor based off these settings - * var Video = query.toConstructor(); - * - * // Video is now a subclass of mquery() and works the same way but with the - * // default query parameters and options set. - * - * // run a query with the previous settings but filter for movies with names - * // that start with "Life". - * Video().where({ name: /^Life/ }).exec(cb); - * - * @return {Query} new Query - * @api public - */ - -Query.prototype.toConstructor = function toConstructor() { - function CustomQuery(criteria, options) { - if (!(this instanceof CustomQuery)) - return new CustomQuery(criteria, options); - Query.call(this, criteria, options); - } - - utils.inherits(CustomQuery, Query); - - // set inherited defaults - var p = CustomQuery.prototype; - - p.options = {}; - p.setOptions(this.options); - - p.op = this.op; - p._conditions = utils.clone(this._conditions); - p._fields = utils.clone(this._fields); - p._update = utils.clone(this._update); - p._path = this._path; - p._distinct = this._distinct; - p._collection = this._collection; - p._traceFunction = this._traceFunction; - - return CustomQuery; -}; - -/** - * Sets query options. - * - * ####Options: - * - * - [tailable](http://www.mongodb.org/display/DOCS/Tailable+Cursors) * - * - [sort](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7Bsort(\)%7D%7D) * - * - [limit](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7Blimit%28%29%7D%7D) * - * - [skip](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7Bskip%28%29%7D%7D) * - * - [maxScan](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24maxScan) * - * - [maxTime](http://docs.mongodb.org/manual/reference/operator/meta/maxTimeMS/#op._S_maxTimeMS) * - * - [batchSize](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7BbatchSize%28%29%7D%7D) * - * - [comment](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24comment) * - * - [snapshot](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7Bsnapshot%28%29%7D%7D) * - * - [hint](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24hint) * - * - [slaveOk](http://docs.mongodb.org/manual/applications/replication/#read-preference) * - * - [safe](http://www.mongodb.org/display/DOCS/getLastError+Command) - * - collection the collection to query against - * - * _* denotes a query helper method is also available_ - * - * @param {Object} options - * @api public - */ - -Query.prototype.setOptions = function(options) { - if (!(options && utils.isObject(options))) - return this; - - // set arbitrary options - var methods = utils.keys(options), - method; - - for (var i = 0; i < methods.length; ++i) { - method = methods[i]; - - // use methods if exist (safer option manipulation) - if ('function' == typeof this[method]) { - var args = utils.isArray(options[method]) - ? options[method] - : [options[method]]; - this[method].apply(this, args); - } else { - this.options[method] = options[method]; - } - } - - return this; -}; - -/** - * Sets this Querys collection. - * - * @param {Collection} coll - * @return {Query} this - */ - -Query.prototype.collection = function collection(coll) { - this._collection = new Query.Collection(coll); - - return this; -}; - -/** - * Adds a collation to this op (MongoDB 3.4 and up) - * - * ####Example - * - * query.find().collation({ locale: "en_US", strength: 1 }) - * - * @param {Object} value - * @return {Query} this - * @see MongoDB docs https://docs.mongodb.com/manual/reference/method/cursor.collation/#cursor.collation - * @api public - */ - -Query.prototype.collation = function(value) { - this.options.collation = value; - return this; -}; - -/** - * Specifies a `$where` condition - * - * Use `$where` when you need to select documents using a JavaScript expression. - * - * ####Example - * - * query.$where('this.comments.length > 10 || this.name.length > 5') - * - * query.$where(function () { - * return this.comments.length > 10 || this.name.length > 5; - * }) - * - * @param {String|Function} js javascript string or function - * @return {Query} this - * @memberOf Query - * @method $where - * @api public - */ - -Query.prototype.$where = function(js) { - this._conditions.$where = js; - return this; -}; - -/** - * Specifies a `path` for use with chaining. - * - * ####Example - * - * // instead of writing: - * User.find({age: {$gte: 21, $lte: 65}}, callback); - * - * // we can instead write: - * User.where('age').gte(21).lte(65); - * - * // passing query conditions is permitted - * User.find().where({ name: 'vonderful' }) - * - * // chaining - * User - * .where('age').gte(21).lte(65) - * .where('name', /^vonderful/i) - * .where('friends').slice(10) - * .exec(callback) - * - * @param {String} [path] - * @param {Object} [val] - * @return {Query} this - * @api public - */ - -Query.prototype.where = function() { - if (!arguments.length) return this; - if (!this.op) this.op = 'find'; - - var type = typeof arguments[0]; - - if ('string' == type) { - this._path = arguments[0]; - - if (2 === arguments.length) { - this._conditions[this._path] = arguments[1]; - } - - return this; - } - - if ('object' == type && !Array.isArray(arguments[0])) { - return this.merge(arguments[0]); - } - - throw new TypeError('path must be a string or object'); -}; - -/** - * Specifies the complementary comparison value for paths specified with `where()` - * - * ####Example - * - * User.where('age').equals(49); - * - * // is the same as - * - * User.where('age', 49); - * - * @param {Object} val - * @return {Query} this - * @api public - */ - -Query.prototype.equals = function equals(val) { - this._ensurePath('equals'); - var path = this._path; - this._conditions[path] = val; - return this; -}; - -/** - * Specifies the complementary comparison value for paths specified with `where()` - * This is alias of `equals` - * - * ####Example - * - * User.where('age').eq(49); - * - * // is the same as - * - * User.shere('age').equals(49); - * - * // is the same as - * - * User.where('age', 49); - * - * @param {Object} val - * @return {Query} this - * @api public - */ - -Query.prototype.eq = function eq(val) { - this._ensurePath('eq'); - var path = this._path; - this._conditions[path] = val; - return this; -}; - -/** - * Specifies arguments for an `$or` condition. - * - * ####Example - * - * query.or([{ color: 'red' }, { status: 'emergency' }]) - * - * @param {Array} array array of conditions - * @return {Query} this - * @api public - */ - -Query.prototype.or = function or(array) { - var or = this._conditions.$or || (this._conditions.$or = []); - if (!utils.isArray(array)) array = [array]; - or.push.apply(or, array); - return this; -}; - -/** - * Specifies arguments for a `$nor` condition. - * - * ####Example - * - * query.nor([{ color: 'green' }, { status: 'ok' }]) - * - * @param {Array} array array of conditions - * @return {Query} this - * @api public - */ - -Query.prototype.nor = function nor(array) { - var nor = this._conditions.$nor || (this._conditions.$nor = []); - if (!utils.isArray(array)) array = [array]; - nor.push.apply(nor, array); - return this; -}; - -/** - * Specifies arguments for a `$and` condition. - * - * ####Example - * - * query.and([{ color: 'green' }, { status: 'ok' }]) - * - * @see $and http://docs.mongodb.org/manual/reference/operator/and/ - * @param {Array} array array of conditions - * @return {Query} this - * @api public - */ - -Query.prototype.and = function and(array) { - var and = this._conditions.$and || (this._conditions.$and = []); - if (!Array.isArray(array)) array = [array]; - and.push.apply(and, array); - return this; -}; - -/** - * Specifies a $gt query condition. - * - * When called with one argument, the most recent path passed to `where()` is used. - * - * ####Example - * - * Thing.find().where('age').gt(21) - * - * // or - * Thing.find().gt('age', 21) - * - * @method gt - * @memberOf Query - * @param {String} [path] - * @param {Number} val - * @api public - */ - -/** - * Specifies a $gte query condition. - * - * When called with one argument, the most recent path passed to `where()` is used. - * - * @method gte - * @memberOf Query - * @param {String} [path] - * @param {Number} val - * @api public - */ - -/** - * Specifies a $lt query condition. - * - * When called with one argument, the most recent path passed to `where()` is used. - * - * @method lt - * @memberOf Query - * @param {String} [path] - * @param {Number} val - * @api public - */ - -/** - * Specifies a $lte query condition. - * - * When called with one argument, the most recent path passed to `where()` is used. - * - * @method lte - * @memberOf Query - * @param {String} [path] - * @param {Number} val - * @api public - */ - -/** - * Specifies a $ne query condition. - * - * When called with one argument, the most recent path passed to `where()` is used. - * - * @method ne - * @memberOf Query - * @param {String} [path] - * @param {Number} val - * @api public - */ - -/** - * Specifies an $in query condition. - * - * When called with one argument, the most recent path passed to `where()` is used. - * - * @method in - * @memberOf Query - * @param {String} [path] - * @param {Number} val - * @api public - */ - -/** - * Specifies an $nin query condition. - * - * When called with one argument, the most recent path passed to `where()` is used. - * - * @method nin - * @memberOf Query - * @param {String} [path] - * @param {Number} val - * @api public - */ - -/** - * Specifies an $all query condition. - * - * When called with one argument, the most recent path passed to `where()` is used. - * - * @method all - * @memberOf Query - * @param {String} [path] - * @param {Number} val - * @api public - */ - -/** - * Specifies a $size query condition. - * - * When called with one argument, the most recent path passed to `where()` is used. - * - * @method size - * @memberOf Query - * @param {String} [path] - * @param {Number} val - * @api public - */ - -/** - * Specifies a $regex query condition. - * - * When called with one argument, the most recent path passed to `where()` is used. - * - * @method regex - * @memberOf Query - * @param {String} [path] - * @param {String|RegExp} val - * @api public - */ - -/** - * Specifies a $maxDistance query condition. - * - * When called with one argument, the most recent path passed to `where()` is used. - * - * @method maxDistance - * @memberOf Query - * @param {String} [path] - * @param {Number} val - * @api public - */ - -/*! - * gt, gte, lt, lte, ne, in, nin, all, regex, size, maxDistance - * - * Thing.where('type').nin(array) - */ - -'gt gte lt lte ne in nin all regex size maxDistance minDistance'.split(' ').forEach(function($conditional) { - Query.prototype[$conditional] = function() { - var path, val; - - if (1 === arguments.length) { - this._ensurePath($conditional); - val = arguments[0]; - path = this._path; - } else { - val = arguments[1]; - path = arguments[0]; - } - - var conds = this._conditions[path] === null || typeof this._conditions[path] === 'object' ? - this._conditions[path] : - (this._conditions[path] = {}); - conds['$' + $conditional] = val; - return this; - }; -}); - -/** - * Specifies a `$mod` condition - * - * @param {String} [path] - * @param {Number} val - * @return {Query} this - * @api public - */ - -Query.prototype.mod = function() { - var val, path; - - if (1 === arguments.length) { - this._ensurePath('mod'); - val = arguments[0]; - path = this._path; - } else if (2 === arguments.length && !utils.isArray(arguments[1])) { - this._ensurePath('mod'); - val = slice(arguments); - path = this._path; - } else if (3 === arguments.length) { - val = slice(arguments, 1); - path = arguments[0]; - } else { - val = arguments[1]; - path = arguments[0]; - } - - var conds = this._conditions[path] || (this._conditions[path] = {}); - conds.$mod = val; - return this; -}; - -/** - * Specifies an `$exists` condition - * - * ####Example - * - * // { name: { $exists: true }} - * Thing.where('name').exists() - * Thing.where('name').exists(true) - * Thing.find().exists('name') - * - * // { name: { $exists: false }} - * Thing.where('name').exists(false); - * Thing.find().exists('name', false); - * - * @param {String} [path] - * @param {Number} val - * @return {Query} this - * @api public - */ - -Query.prototype.exists = function() { - var path, val; - - if (0 === arguments.length) { - this._ensurePath('exists'); - path = this._path; - val = true; - } else if (1 === arguments.length) { - if ('boolean' === typeof arguments[0]) { - this._ensurePath('exists'); - path = this._path; - val = arguments[0]; - } else { - path = arguments[0]; - val = true; - } - } else if (2 === arguments.length) { - path = arguments[0]; - val = arguments[1]; - } - - var conds = this._conditions[path] || (this._conditions[path] = {}); - conds.$exists = val; - return this; -}; - -/** - * Specifies an `$elemMatch` condition - * - * ####Example - * - * query.elemMatch('comment', { author: 'autobot', votes: {$gte: 5}}) - * - * query.where('comment').elemMatch({ author: 'autobot', votes: {$gte: 5}}) - * - * query.elemMatch('comment', function (elem) { - * elem.where('author').equals('autobot'); - * elem.where('votes').gte(5); - * }) - * - * query.where('comment').elemMatch(function (elem) { - * elem.where({ author: 'autobot' }); - * elem.where('votes').gte(5); - * }) - * - * @param {String|Object|Function} path - * @param {Object|Function} criteria - * @return {Query} this - * @api public - */ - -Query.prototype.elemMatch = function() { - if (null == arguments[0]) - throw new TypeError('Invalid argument'); - - var fn, path, criteria; - - if ('function' === typeof arguments[0]) { - this._ensurePath('elemMatch'); - path = this._path; - fn = arguments[0]; - } else if (utils.isObject(arguments[0])) { - this._ensurePath('elemMatch'); - path = this._path; - criteria = arguments[0]; - } else if ('function' === typeof arguments[1]) { - path = arguments[0]; - fn = arguments[1]; - } else if (arguments[1] && utils.isObject(arguments[1])) { - path = arguments[0]; - criteria = arguments[1]; - } else { - throw new TypeError('Invalid argument'); - } - - if (fn) { - criteria = new Query; - fn(criteria); - criteria = criteria._conditions; - } - - var conds = this._conditions[path] || (this._conditions[path] = {}); - conds.$elemMatch = criteria; - return this; -}; - -// Spatial queries - -/** - * Sugar for geo-spatial queries. - * - * ####Example - * - * query.within().box() - * query.within().circle() - * query.within().geometry() - * - * query.where('loc').within({ center: [50,50], radius: 10, unique: true, spherical: true }); - * query.where('loc').within({ box: [[40.73, -73.9], [40.7, -73.988]] }); - * query.where('loc').within({ polygon: [[],[],[],[]] }); - * - * query.where('loc').within([], [], []) // polygon - * query.where('loc').within([], []) // box - * query.where('loc').within({ type: 'LineString', coordinates: [...] }); // geometry - * - * ####NOTE: - * - * Must be used after `where()`. - * - * @memberOf Query - * @return {Query} this - * @api public - */ - -Query.prototype.within = function within() { - // opinionated, must be used after where - this._ensurePath('within'); - this._geoComparison = $withinCmd; - - if (0 === arguments.length) { - return this; - } - - if (2 === arguments.length) { - return this.box.apply(this, arguments); - } else if (2 < arguments.length) { - return this.polygon.apply(this, arguments); - } - - var area = arguments[0]; - - if (!area) - throw new TypeError('Invalid argument'); - - if (area.center) - return this.circle(area); - - if (area.box) - return this.box.apply(this, area.box); - - if (area.polygon) - return this.polygon.apply(this, area.polygon); - - if (area.type && area.coordinates) - return this.geometry(area); - - throw new TypeError('Invalid argument'); -}; - -/** - * Specifies a $box condition - * - * ####Example - * - * var lowerLeft = [40.73083, -73.99756] - * var upperRight= [40.741404, -73.988135] - * - * query.where('loc').within().box(lowerLeft, upperRight) - * query.box('loc', lowerLeft, upperRight ) - * - * @see http://www.mongodb.org/display/DOCS/Geospatial+Indexing - * @see Query#within #query_Query-within - * @param {String} path - * @param {Object} val - * @return {Query} this - * @api public - */ - -Query.prototype.box = function() { - var path, box; - - if (3 === arguments.length) { - // box('loc', [], []) - path = arguments[0]; - box = [arguments[1], arguments[2]]; - } else if (2 === arguments.length) { - // box([], []) - this._ensurePath('box'); - path = this._path; - box = [arguments[0], arguments[1]]; - } else { - throw new TypeError('Invalid argument'); - } - - var conds = this._conditions[path] || (this._conditions[path] = {}); - conds[this._geoComparison || $withinCmd] = { '$box': box }; - return this; -}; - -/** - * Specifies a $polygon condition - * - * ####Example - * - * query.where('loc').within().polygon([10,20], [13, 25], [7,15]) - * query.polygon('loc', [10,20], [13, 25], [7,15]) - * - * @param {String|Array} [path] - * @param {Array|Object} [val] - * @return {Query} this - * @see http://www.mongodb.org/display/DOCS/Geospatial+Indexing - * @api public - */ - -Query.prototype.polygon = function() { - var val, path; - - if ('string' == typeof arguments[0]) { - // polygon('loc', [],[],[]) - path = arguments[0]; - val = slice(arguments, 1); - } else { - // polygon([],[],[]) - this._ensurePath('polygon'); - path = this._path; - val = slice(arguments); - } - - var conds = this._conditions[path] || (this._conditions[path] = {}); - conds[this._geoComparison || $withinCmd] = { '$polygon': val }; - return this; -}; - -/** - * Specifies a $center or $centerSphere condition. - * - * ####Example - * - * var area = { center: [50, 50], radius: 10, unique: true } - * query.where('loc').within().circle(area) - * query.center('loc', area); - * - * // for spherical calculations - * var area = { center: [50, 50], radius: 10, unique: true, spherical: true } - * query.where('loc').within().circle(area) - * query.center('loc', area); - * - * @param {String} [path] - * @param {Object} area - * @return {Query} this - * @see http://www.mongodb.org/display/DOCS/Geospatial+Indexing - * @api public - */ - -Query.prototype.circle = function() { - var path, val; - - if (1 === arguments.length) { - this._ensurePath('circle'); - path = this._path; - val = arguments[0]; - } else if (2 === arguments.length) { - path = arguments[0]; - val = arguments[1]; - } else { - throw new TypeError('Invalid argument'); - } - - if (!('radius' in val && val.center)) - throw new Error('center and radius are required'); - - var conds = this._conditions[path] || (this._conditions[path] = {}); - - var type = val.spherical - ? '$centerSphere' - : '$center'; - - var wKey = this._geoComparison || $withinCmd; - conds[wKey] = {}; - conds[wKey][type] = [val.center, val.radius]; - - if ('unique' in val) - conds[wKey].$uniqueDocs = !!val.unique; - - return this; -}; - -/** - * Specifies a `$near` or `$nearSphere` condition - * - * These operators return documents sorted by distance. - * - * ####Example - * - * query.where('loc').near({ center: [10, 10] }); - * query.where('loc').near({ center: [10, 10], maxDistance: 5 }); - * query.where('loc').near({ center: [10, 10], maxDistance: 5, spherical: true }); - * query.near('loc', { center: [10, 10], maxDistance: 5 }); - * query.near({ center: { type: 'Point', coordinates: [..] }}) - * query.near().geometry({ type: 'Point', coordinates: [..] }) - * - * @param {String} [path] - * @param {Object} val - * @return {Query} this - * @see http://www.mongodb.org/display/DOCS/Geospatial+Indexing - * @api public - */ - -Query.prototype.near = function near() { - var path, val; - - this._geoComparison = '$near'; - - if (0 === arguments.length) { - return this; - } else if (1 === arguments.length) { - this._ensurePath('near'); - path = this._path; - val = arguments[0]; - } else if (2 === arguments.length) { - path = arguments[0]; - val = arguments[1]; - } else { - throw new TypeError('Invalid argument'); - } - - if (!val.center) { - throw new Error('center is required'); - } - - var conds = this._conditions[path] || (this._conditions[path] = {}); - - var type = val.spherical - ? '$nearSphere' - : '$near'; - - // center could be a GeoJSON object or an Array - if (Array.isArray(val.center)) { - conds[type] = val.center; - - var radius = 'maxDistance' in val - ? val.maxDistance - : null; - - if (null != radius) { - conds.$maxDistance = radius; - } - if (null != val.minDistance) { - conds.$minDistance = val.minDistance; - } - } else { - // GeoJSON? - if (val.center.type != 'Point' || !Array.isArray(val.center.coordinates)) { - throw new Error(util.format('Invalid GeoJSON specified for %s', type)); - } - conds[type] = { $geometry : val.center }; - - // MongoDB 2.6 insists on maxDistance being in $near / $nearSphere - if ('maxDistance' in val) { - conds[type]['$maxDistance'] = val.maxDistance; - } - if ('minDistance' in val) { - conds[type]['$minDistance'] = val.minDistance; - } - } - - return this; -}; - -/** - * Declares an intersects query for `geometry()`. - * - * ####Example - * - * query.where('path').intersects().geometry({ - * type: 'LineString' - * , coordinates: [[180.0, 11.0], [180, 9.0]] - * }) - * - * query.where('path').intersects({ - * type: 'LineString' - * , coordinates: [[180.0, 11.0], [180, 9.0]] - * }) - * - * @param {Object} [arg] - * @return {Query} this - * @api public - */ - -Query.prototype.intersects = function intersects() { - // opinionated, must be used after where - this._ensurePath('intersects'); - - this._geoComparison = '$geoIntersects'; - - if (0 === arguments.length) { - return this; - } - - var area = arguments[0]; - - if (null != area && area.type && area.coordinates) - return this.geometry(area); - - throw new TypeError('Invalid argument'); -}; - -/** - * Specifies a `$geometry` condition - * - * ####Example - * - * var polyA = [[[ 10, 20 ], [ 10, 40 ], [ 30, 40 ], [ 30, 20 ]]] - * query.where('loc').within().geometry({ type: 'Polygon', coordinates: polyA }) - * - * // or - * var polyB = [[ 0, 0 ], [ 1, 1 ]] - * query.where('loc').within().geometry({ type: 'LineString', coordinates: polyB }) - * - * // or - * var polyC = [ 0, 0 ] - * query.where('loc').within().geometry({ type: 'Point', coordinates: polyC }) - * - * // or - * query.where('loc').intersects().geometry({ type: 'Point', coordinates: polyC }) - * - * ####NOTE: - * - * `geometry()` **must** come after either `intersects()` or `within()`. - * - * The `object` argument must contain `type` and `coordinates` properties. - * - type {String} - * - coordinates {Array} - * - * The most recent path passed to `where()` is used. - * - * @param {Object} object Must contain a `type` property which is a String and a `coordinates` property which is an Array. See the examples. - * @return {Query} this - * @see http://docs.mongodb.org/manual/release-notes/2.4/#new-geospatial-indexes-with-geojson-and-improved-spherical-geometry - * @see http://www.mongodb.org/display/DOCS/Geospatial+Indexing - * @see $geometry http://docs.mongodb.org/manual/reference/operator/geometry/ - * @api public - */ - -Query.prototype.geometry = function geometry() { - if (!('$within' == this._geoComparison || - '$geoWithin' == this._geoComparison || - '$near' == this._geoComparison || - '$geoIntersects' == this._geoComparison)) { - throw new Error('geometry() must come after `within()`, `intersects()`, or `near()'); - } - - var val, path; - - if (1 === arguments.length) { - this._ensurePath('geometry'); - path = this._path; - val = arguments[0]; - } else { - throw new TypeError('Invalid argument'); - } - - if (!(val.type && Array.isArray(val.coordinates))) { - throw new TypeError('Invalid argument'); - } - - var conds = this._conditions[path] || (this._conditions[path] = {}); - conds[this._geoComparison] = { $geometry: val }; - - return this; -}; - -// end spatial - -/** - * Specifies which document fields to include or exclude - * - * ####String syntax - * - * When passing a string, prefixing a path with `-` will flag that path as excluded. When a path does not have the `-` prefix, it is included. - * - * ####Example - * - * // include a and b, exclude c - * query.select('a b -c'); - * - * // or you may use object notation, useful when - * // you have keys already prefixed with a "-" - * query.select({a: 1, b: 1, c: 0}); - * - * ####Note - * - * Cannot be used with `distinct()` - * - * @param {Object|String} arg - * @return {Query} this - * @see SchemaType - * @api public - */ - -Query.prototype.select = function select() { - var arg = arguments[0]; - if (!arg) return this; - - if (arguments.length !== 1) { - throw new Error('Invalid select: select only takes 1 argument'); - } - - this._validate('select'); - - var fields = this._fields || (this._fields = {}); - var type = typeof arg; - var i, len; - - if (('string' == type || utils.isArgumentsObject(arg)) && - 'number' == typeof arg.length || Array.isArray(arg)) { - if ('string' == type) - arg = arg.split(/\s+/); - - for (i = 0, len = arg.length; i < len; ++i) { - var field = arg[i]; - if (!field) continue; - var include = '-' == field[0] ? 0 : 1; - if (include === 0) field = field.substring(1); - fields[field] = include; - } - - return this; - } - - if (utils.isObject(arg)) { - var keys = utils.keys(arg); - for (i = 0; i < keys.length; ++i) { - fields[keys[i]] = arg[keys[i]]; - } - return this; - } - - throw new TypeError('Invalid select() argument. Must be string or object.'); -}; - -/** - * Specifies a $slice condition for a `path` - * - * ####Example - * - * query.slice('comments', 5) - * query.slice('comments', -5) - * query.slice('comments', [10, 5]) - * query.where('comments').slice(5) - * query.where('comments').slice([-10, 5]) - * - * @param {String} [path] - * @param {Number} val number/range of elements to slice - * @return {Query} this - * @see mongodb http://www.mongodb.org/display/DOCS/Retrieving+a+Subset+of+Fields#RetrievingaSubsetofFields-RetrievingaSubrangeofArrayElements - * @api public - */ - -Query.prototype.slice = function() { - if (0 === arguments.length) - return this; - - this._validate('slice'); - - var path, val; - - if (1 === arguments.length) { - var arg = arguments[0]; - if (typeof arg === 'object' && !Array.isArray(arg)) { - var keys = Object.keys(arg); - var numKeys = keys.length; - for (var i = 0; i < numKeys; ++i) { - this.slice(keys[i], arg[keys[i]]); - } - return this; - } - this._ensurePath('slice'); - path = this._path; - val = arguments[0]; - } else if (2 === arguments.length) { - if ('number' === typeof arguments[0]) { - this._ensurePath('slice'); - path = this._path; - val = slice(arguments); - } else { - path = arguments[0]; - val = arguments[1]; - } - } else if (3 === arguments.length) { - path = arguments[0]; - val = slice(arguments, 1); - } - - var myFields = this._fields || (this._fields = {}); - myFields[path] = { '$slice': val }; - return this; -}; - -/** - * Sets the sort order - * - * If an object is passed, values allowed are 'asc', 'desc', 'ascending', 'descending', 1, and -1. - * - * If a string is passed, it must be a space delimited list of path names. The sort order of each path is ascending unless the path name is prefixed with `-` which will be treated as descending. - * - * ####Example - * - * // these are equivalent - * query.sort({ field: 'asc', test: -1 }); - * query.sort('field -test'); - * query.sort([['field', 1], ['test', -1]]); - * - * ####Note - * - * - The array syntax `.sort([['field', 1], ['test', -1]])` can only be used with [mongodb driver >= 2.0.46](https://github.com/mongodb/node-mongodb-native/blob/2.1/HISTORY.md#2046-2015-10-15). - * - Cannot be used with `distinct()` - * - * @param {Object|String|Array} arg - * @return {Query} this - * @api public - */ - -Query.prototype.sort = function(arg) { - if (!arg) return this; - var i, len, field; - - this._validate('sort'); - - var type = typeof arg; - - // .sort([['field', 1], ['test', -1]]) - if (Array.isArray(arg)) { - len = arg.length; - for (i = 0; i < arg.length; ++i) { - if (!Array.isArray(arg[i])) { - throw new Error('Invalid sort() argument, must be array of arrays'); - } - _pushArr(this.options, arg[i][0], arg[i][1]); - } - return this; - } - - // .sort('field -test') - if (1 === arguments.length && 'string' == type) { - arg = arg.split(/\s+/); - len = arg.length; - for (i = 0; i < len; ++i) { - field = arg[i]; - if (!field) continue; - var ascend = '-' == field[0] ? -1 : 1; - if (ascend === -1) field = field.substring(1); - push(this.options, field, ascend); - } - - return this; - } - - // .sort({ field: 1, test: -1 }) - if (utils.isObject(arg)) { - var keys = utils.keys(arg); - for (i = 0; i < keys.length; ++i) { - field = keys[i]; - push(this.options, field, arg[field]); - } - - return this; - } - - if (typeof Map !== 'undefined' && arg instanceof Map) { - _pushMap(this.options, arg); - return this; - } - throw new TypeError('Invalid sort() argument. Must be a string, object, or array.'); -}; - -/*! - * @ignore - */ - -var _validSortValue = { - '1': 1, - '-1': -1, - 'asc': 1, - 'ascending': 1, - 'desc': -1, - 'descending': -1 -}; - -function push(opts, field, value) { - if (Array.isArray(opts.sort)) { - throw new TypeError('Can\'t mix sort syntaxes. Use either array or object:' + - '\n- `.sort([[\'field\', 1], [\'test\', -1]])`' + - '\n- `.sort({ field: 1, test: -1 })`'); - } - - var s; - if (value && value.$meta) { - s = opts.sort || (opts.sort = {}); - s[field] = { $meta : value.$meta }; - return; - } - - s = opts.sort || (opts.sort = {}); - var val = String(value || 1).toLowerCase(); - val = _validSortValue[val]; - if (!val) throw new TypeError('Invalid sort value: { ' + field + ': ' + value + ' }'); - - s[field] = val; -} - -function _pushArr(opts, field, value) { - opts.sort = opts.sort || []; - if (!Array.isArray(opts.sort)) { - throw new TypeError('Can\'t mix sort syntaxes. Use either array or object:' + - '\n- `.sort([[\'field\', 1], [\'test\', -1]])`' + - '\n- `.sort({ field: 1, test: -1 })`'); - } - - var val = String(value || 1).toLowerCase(); - val = _validSortValue[val]; - if (!val) throw new TypeError('Invalid sort value: [ ' + field + ', ' + value + ' ]'); - - opts.sort.push([field, val]); -} - -function _pushMap(opts, map) { - opts.sort = opts.sort || new Map(); - if (!(opts.sort instanceof Map)) { - throw new TypeError('Can\'t mix sort syntaxes. Use either array or ' + - 'object or map consistently'); - } - map.forEach(function(value, key) { - var val = String(value || 1).toLowerCase(); - val = _validSortValue[val]; - if (!val) throw new TypeError('Invalid sort value: < ' + key + ': ' + value + ' >'); - - opts.sort.set(key, val); - }); -} - - - -/** - * Specifies the limit option. - * - * ####Example - * - * query.limit(20) - * - * ####Note - * - * Cannot be used with `distinct()` - * - * @method limit - * @memberOf Query - * @param {Number} val - * @see mongodb http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7Blimit%28%29%7D%7D - * @api public - */ -/** - * Specifies the skip option. - * - * ####Example - * - * query.skip(100).limit(20) - * - * ####Note - * - * Cannot be used with `distinct()` - * - * @method skip - * @memberOf Query - * @param {Number} val - * @see mongodb http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7Bskip%28%29%7D%7D - * @api public - */ -/** - * Specifies the maxScan option. - * - * ####Example - * - * query.maxScan(100) - * - * ####Note - * - * Cannot be used with `distinct()` - * - * @method maxScan - * @memberOf Query - * @param {Number} val - * @see mongodb http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24maxScan - * @api public - */ -/** - * Specifies the batchSize option. - * - * ####Example - * - * query.batchSize(100) - * - * ####Note - * - * Cannot be used with `distinct()` - * - * @method batchSize - * @memberOf Query - * @param {Number} val - * @see mongodb http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7BbatchSize%28%29%7D%7D - * @api public - */ -/** - * Specifies the `comment` option. - * - * ####Example - * - * query.comment('login query') - * - * ####Note - * - * Cannot be used with `distinct()` - * - * @method comment - * @memberOf Query - * @param {Number} val - * @see mongodb http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24comment - * @api public - */ - -/*! - * limit, skip, maxScan, batchSize, comment - * - * Sets these associated options. - * - * query.comment('feed query'); - */ - -['limit', 'skip', 'maxScan', 'batchSize', 'comment'].forEach(function(method) { - Query.prototype[method] = function(v) { - this._validate(method); - this.options[method] = v; - return this; - }; -}); - -/** - * Specifies the maxTimeMS option. - * - * ####Example - * - * query.maxTime(100) - * query.maxTimeMS(100) - * - * @method maxTime - * @memberOf Query - * @param {Number} ms - * @see mongodb http://docs.mongodb.org/manual/reference/operator/meta/maxTimeMS/#op._S_maxTimeMS - * @api public - */ - -Query.prototype.maxTime = Query.prototype.maxTimeMS = function(ms) { - this._validate('maxTime'); - this.options.maxTimeMS = ms; - return this; -}; - -/** - * Specifies this query as a `snapshot` query. - * - * ####Example - * - * mquery().snapshot() // true - * mquery().snapshot(true) - * mquery().snapshot(false) - * - * ####Note - * - * Cannot be used with `distinct()` - * - * @see mongodb http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7Bsnapshot%28%29%7D%7D - * @return {Query} this - * @api public - */ - -Query.prototype.snapshot = function() { - this._validate('snapshot'); - - this.options.snapshot = arguments.length - ? !!arguments[0] - : true; - - return this; -}; - -/** - * Sets query hints. - * - * ####Example - * - * query.hint({ indexA: 1, indexB: -1}); - * query.hint('indexA_1_indexB_1'); - * - * ####Note - * - * Cannot be used with `distinct()` - * - * @param {Object|string} val a hint object or the index name - * @return {Query} this - * @see mongodb http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24hint - * @api public - */ - -Query.prototype.hint = function() { - if (0 === arguments.length) return this; - - this._validate('hint'); - - var arg = arguments[0]; - if (utils.isObject(arg)) { - var hint = this.options.hint || (this.options.hint = {}); - - // must keep object keys in order so don't use Object.keys() - for (var k in arg) { - hint[k] = arg[k]; - } - - return this; - } - if (typeof arg === 'string') { - this.options.hint = arg; - return this; - } - - throw new TypeError('Invalid hint. ' + arg); -}; - -/** - * Requests acknowledgement that this operation has been persisted to MongoDB's - * on-disk journal. - * This option is only valid for operations that write to the database: - * - * - `deleteOne()` - * - `deleteMany()` - * - `findOneAndDelete()` - * - `findOneAndUpdate()` - * - `remove()` - * - `update()` - * - `updateOne()` - * - `updateMany()` - * - * Defaults to the `j` value if it is specified in writeConcern options - * - * ####Example: - * - * mquery().w(2).j(true).wtimeout(2000); - * - * @method j - * @memberOf Query - * @instance - * @param {boolean} val - * @see mongodb https://docs.mongodb.com/manual/reference/write-concern/#j-option - * @return {Query} this - * @api public - */ - -Query.prototype.j = function j(val) { - this.options.j = val; - return this; -}; - -/** - * Sets the slaveOk option. _Deprecated_ in MongoDB 2.2 in favor of read preferences. - * - * ####Example: - * - * query.slaveOk() // true - * query.slaveOk(true) - * query.slaveOk(false) - * - * @deprecated use read() preferences instead if on mongodb >= 2.2 - * @param {Boolean} v defaults to true - * @see mongodb http://docs.mongodb.org/manual/applications/replication/#read-preference - * @see read() - * @return {Query} this - * @api public - */ - -Query.prototype.slaveOk = function(v) { - this.options.slaveOk = arguments.length ? !!v : true; - return this; -}; - -/** - * Sets the readPreference option for the query. - * - * ####Example: - * - * new Query().read('primary') - * new Query().read('p') // same as primary - * - * new Query().read('primaryPreferred') - * new Query().read('pp') // same as primaryPreferred - * - * new Query().read('secondary') - * new Query().read('s') // same as secondary - * - * new Query().read('secondaryPreferred') - * new Query().read('sp') // same as secondaryPreferred - * - * new Query().read('nearest') - * new Query().read('n') // same as nearest - * - * // you can also use mongodb.ReadPreference class to also specify tags - * new Query().read(mongodb.ReadPreference('secondary', [{ dc:'sf', s: 1 },{ dc:'ma', s: 2 }])) - * - * new Query().setReadPreference('primary') // alias of .read() - * - * ####Preferences: - * - * primary - (default) Read from primary only. Operations will produce an error if primary is unavailable. Cannot be combined with tags. - * secondary Read from secondary if available, otherwise error. - * primaryPreferred Read from primary if available, otherwise a secondary. - * secondaryPreferred Read from a secondary if available, otherwise read from the primary. - * nearest All operations read from among the nearest candidates, but unlike other modes, this option will include both the primary and all secondaries in the random selection. - * - * Aliases - * - * p primary - * pp primaryPreferred - * s secondary - * sp secondaryPreferred - * n nearest - * - * Read more about how to use read preferences [here](http://docs.mongodb.org/manual/applications/replication/#read-preference) and [here](http://mongodb.github.com/node-mongodb-native/driver-articles/anintroductionto1_1and2_2.html#read-preferences). - * - * @param {String|ReadPreference} pref one of the listed preference options or their aliases - * @see mongodb http://docs.mongodb.org/manual/applications/replication/#read-preference - * @see driver http://mongodb.github.com/node-mongodb-native/driver-articles/anintroductionto1_1and2_2.html#read-preferences - * @return {Query} this - * @api public - */ - -Query.prototype.read = Query.prototype.setReadPreference = function(pref) { - if (arguments.length > 1 && !Query.prototype.read.deprecationWarningIssued) { - console.error('Deprecation warning: \'tags\' argument is not supported anymore in Query.read() method. Please use mongodb.ReadPreference object instead.'); - Query.prototype.read.deprecationWarningIssued = true; - } - this.options.readPreference = utils.readPref(pref); - return this; -}; - -/** - * Sets the readConcern option for the query. - * - * ####Example: - * - * new Query().readConcern('local') - * new Query().readConcern('l') // same as local - * - * new Query().readConcern('available') - * new Query().readConcern('a') // same as available - * - * new Query().readConcern('majority') - * new Query().readConcern('m') // same as majority - * - * new Query().readConcern('linearizable') - * new Query().readConcern('lz') // same as linearizable - * - * new Query().readConcern('snapshot') - * new Query().readConcern('s') // same as snapshot - * - * new Query().r('s') // r is alias of readConcern - * - * - * ####Read Concern Level: - * - * local MongoDB 3.2+ The query returns from the instance with no guarantee guarantee that the data has been written to a majority of the replica set members (i.e. may be rolled back). - * available MongoDB 3.6+ The query returns from the instance with no guarantee guarantee that the data has been written to a majority of the replica set members (i.e. may be rolled back). - * majority MongoDB 3.2+ The query returns the data that has been acknowledged by a majority of the replica set members. The documents returned by the read operation are durable, even in the event of failure. - * linearizable MongoDB 3.4+ The query returns data that reflects all successful majority-acknowledged writes that completed prior to the start of the read operation. The query may wait for concurrently executing writes to propagate to a majority of replica set members before returning results. - * snapshot MongoDB 4.0+ Only available for operations within multi-document transactions. Upon transaction commit with write concern "majority", the transaction operations are guaranteed to have read from a snapshot of majority-committed data. - - - * - * - * Aliases - * - * l local - * a available - * m majority - * lz linearizable - * s snapshot - * - * Read more about how to use read concern [here](https://docs.mongodb.com/manual/reference/read-concern/). - * - * @param {String} level one of the listed read concern level or their aliases - * @see mongodb https://docs.mongodb.com/manual/reference/read-concern/ - * @return {Query} this - * @api public - */ - -Query.prototype.readConcern = Query.prototype.r = function(level) { - this.options.readConcern = utils.readConcern(level); - return this; -}; - -/** - * Sets tailable option. - * - * ####Example - * - * query.tailable() <== true - * query.tailable(true) - * query.tailable(false) - * - * ####Note - * - * Cannot be used with `distinct()` - * - * @param {Boolean} v defaults to true - * @see mongodb http://www.mongodb.org/display/DOCS/Tailable+Cursors - * @api public - */ - -Query.prototype.tailable = function() { - this._validate('tailable'); - - this.options.tailable = arguments.length - ? !!arguments[0] - : true; - - return this; -}; - -/** - * Sets the specified number of `mongod` servers, or tag set of `mongod` servers, - * that must acknowledge this write before this write is considered successful. - * This option is only valid for operations that write to the database: - * - * - `deleteOne()` - * - `deleteMany()` - * - `findOneAndDelete()` - * - `findOneAndUpdate()` - * - `remove()` - * - `update()` - * - `updateOne()` - * - `updateMany()` - * - * Defaults to the `w` value if it is specified in writeConcern options - * - * ####Example: - * - * mquery().writeConcern(0) - * mquery().writeConcern(1) - * mquery().writeConcern({ w: 1, j: true, wtimeout: 2000 }) - * mquery().writeConcern('majority') - * mquery().writeConcern('m') // same as majority - * mquery().writeConcern('tagSetName') // if the tag set is 'm', use .writeConcern({ w: 'm' }) instead - * mquery().w(1) // w is alias of writeConcern - * - * @method writeConcern - * @memberOf Query - * @instance - * @param {String|number|object} concern 0 for fire-and-forget, 1 for acknowledged by one server, 'majority' for majority of the replica set, or [any of the more advanced options](https://docs.mongodb.com/manual/reference/write-concern/#w-option). - * @see mongodb https://docs.mongodb.com/manual/reference/write-concern/#w-option - * @return {Query} this - * @api public - */ - -Query.prototype.writeConcern = Query.prototype.w = function writeConcern(concern) { - if ('object' === typeof concern) { - if ('undefined' !== typeof concern.j) this.options.j = concern.j; - if ('undefined' !== typeof concern.w) this.options.w = concern.w; - if ('undefined' !== typeof concern.wtimeout) this.options.wtimeout = concern.wtimeout; - } else { - this.options.w = 'm' === concern ? 'majority' : concern; - } - return this; -}; - -/** - * Specifies a time limit, in milliseconds, for the write concern. - * If `ms > 1`, it is maximum amount of time to wait for this write - * to propagate through the replica set before this operation fails. - * The default is `0`, which means no timeout. - * - * This option is only valid for operations that write to the database: - * - * - `deleteOne()` - * - `deleteMany()` - * - `findOneAndDelete()` - * - `findOneAndUpdate()` - * - `remove()` - * - `update()` - * - `updateOne()` - * - `updateMany()` - * - * Defaults to `wtimeout` value if it is specified in writeConcern - * - * ####Example: - * - * mquery().w(2).j(true).wtimeout(2000) - * - * @method wtimeout - * @memberOf Query - * @instance - * @param {number} ms number of milliseconds to wait - * @see mongodb https://docs.mongodb.com/manual/reference/write-concern/#wtimeout - * @return {Query} this - * @api public - */ - -Query.prototype.wtimeout = Query.prototype.wTimeout = function wtimeout(ms) { - this.options.wtimeout = ms; - return this; -}; - -/** - * Merges another Query or conditions object into this one. - * - * When a Query is passed, conditions, field selection and options are merged. - * - * @param {Query|Object} source - * @return {Query} this - */ - -Query.prototype.merge = function(source) { - if (!source) - return this; - - if (!Query.canMerge(source)) - throw new TypeError('Invalid argument. Expected instanceof mquery or plain object'); - - if (source instanceof Query) { - // if source has a feature, apply it to ourselves - - if (source._conditions) { - utils.merge(this._conditions, source._conditions); - } - - if (source._fields) { - this._fields || (this._fields = {}); - utils.merge(this._fields, source._fields); - } - - if (source.options) { - this.options || (this.options = {}); - utils.merge(this.options, source.options); - } - - if (source._update) { - this._update || (this._update = {}); - utils.mergeClone(this._update, source._update); - } - - if (source._distinct) { - this._distinct = source._distinct; - } - - return this; - } - - // plain object - utils.merge(this._conditions, source); - - return this; -}; - -/** - * Finds documents. - * - * Passing a `callback` executes the query. - * - * ####Example - * - * query.find() - * query.find(callback) - * query.find({ name: 'Burning Lights' }, callback) - * - * @param {Object} [criteria] mongodb selector - * @param {Function} [callback] - * @return {Query} this - * @api public - */ - -Query.prototype.find = function(criteria, callback) { - this.op = 'find'; - - if ('function' === typeof criteria) { - callback = criteria; - criteria = undefined; - } else if (Query.canMerge(criteria)) { - this.merge(criteria); - } - - if (!callback) return this; - - var conds = this._conditions; - var options = this._optionsForExec(); - - if (this.$useProjection) { - options.projection = this._fieldsForExec(); - } else { - options.fields = this._fieldsForExec(); - } - - debug('find', this._collection.collectionName, conds, options); - callback = this._wrapCallback('find', callback, { - conditions: conds, - options: options - }); - - this._collection.find(conds, options, utils.tick(callback)); - return this; -}; - -/** - * Returns the query cursor - * - * ####Examples - * - * query.find().cursor(); - * query.cursor({ name: 'Burning Lights' }); - * - * @param {Object} [criteria] mongodb selector - * @return {Object} cursor - * @api public - */ - -Query.prototype.cursor = function cursor(criteria) { - if (this.op) { - if (this.op !== 'find') { - throw new TypeError('.cursor only support .find method'); - } - } else { - this.find(criteria); - } - - var conds = this._conditions; - var options = this._optionsForExec(); - - if (this.$useProjection) { - options.projection = this._fieldsForExec(); - } else { - options.fields = this._fieldsForExec(); - } - - debug('findCursor', this._collection.collectionName, conds, options); - return this._collection.findCursor(conds, options); -}; - -/** - * Executes the query as a findOne() operation. - * - * Passing a `callback` executes the query. - * - * ####Example - * - * query.findOne().where('name', /^Burning/); - * - * query.findOne({ name: /^Burning/ }) - * - * query.findOne({ name: /^Burning/ }, callback); // executes - * - * query.findOne(function (err, doc) { - * if (err) return handleError(err); - * if (doc) { - * // doc may be null if no document matched - * - * } - * }); - * - * @param {Object|Query} [criteria] mongodb selector - * @param {Function} [callback] - * @return {Query} this - * @api public - */ - -Query.prototype.findOne = function(criteria, callback) { - this.op = 'findOne'; - - if ('function' === typeof criteria) { - callback = criteria; - criteria = undefined; - } else if (Query.canMerge(criteria)) { - this.merge(criteria); - } - - if (!callback) return this; - - var conds = this._conditions; - var options = this._optionsForExec(); - - if (this.$useProjection) { - options.projection = this._fieldsForExec(); - } else { - options.fields = this._fieldsForExec(); - } - - debug('findOne', this._collection.collectionName, conds, options); - callback = this._wrapCallback('findOne', callback, { - conditions: conds, - options: options - }); - - this._collection.findOne(conds, options, utils.tick(callback)); - - return this; -}; - -/** - * Exectues the query as a count() operation. - * - * Passing a `callback` executes the query. - * - * ####Example - * - * query.count().where('color', 'black').exec(callback); - * - * query.count({ color: 'black' }).count(callback) - * - * query.count({ color: 'black' }, callback) - * - * query.where('color', 'black').count(function (err, count) { - * if (err) return handleError(err); - * console.log('there are %d kittens', count); - * }) - * - * @param {Object} [criteria] mongodb selector - * @param {Function} [callback] - * @return {Query} this - * @see mongodb http://www.mongodb.org/display/DOCS/Aggregation#Aggregation-Count - * @api public - */ - -Query.prototype.count = function(criteria, callback) { - this.op = 'count'; - this._validate(); - - if ('function' === typeof criteria) { - callback = criteria; - criteria = undefined; - } else if (Query.canMerge(criteria)) { - this.merge(criteria); - } - - if (!callback) return this; - - var conds = this._conditions, - options = this._optionsForExec(); - - debug('count', this._collection.collectionName, conds, options); - callback = this._wrapCallback('count', callback, { - conditions: conds, - options: options - }); - - this._collection.count(conds, options, utils.tick(callback)); - return this; -}; - -/** - * Declares or executes a distinct() operation. - * - * Passing a `callback` executes the query. - * - * ####Example - * - * distinct(criteria, field, fn) - * distinct(criteria, field) - * distinct(field, fn) - * distinct(field) - * distinct(fn) - * distinct() - * - * @param {Object|Query} [criteria] - * @param {String} [field] - * @param {Function} [callback] - * @return {Query} this - * @see mongodb http://www.mongodb.org/display/DOCS/Aggregation#Aggregation-Distinct - * @api public - */ - -Query.prototype.distinct = function(criteria, field, callback) { - this.op = 'distinct'; - this._validate(); - - if (!callback) { - switch (typeof field) { - case 'function': - callback = field; - if ('string' == typeof criteria) { - field = criteria; - criteria = undefined; - } - break; - case 'undefined': - case 'string': - break; - default: - throw new TypeError('Invalid `field` argument. Must be string or function'); - } - - switch (typeof criteria) { - case 'function': - callback = criteria; - criteria = field = undefined; - break; - case 'string': - field = criteria; - criteria = undefined; - break; - } - } - - if ('string' == typeof field) { - this._distinct = field; - } - - if (Query.canMerge(criteria)) { - this.merge(criteria); - } - - if (!callback) { - return this; - } - - if (!this._distinct) { - throw new Error('No value for `distinct` has been declared'); - } - - var conds = this._conditions, - options = this._optionsForExec(); - - debug('distinct', this._collection.collectionName, conds, options); - callback = this._wrapCallback('distinct', callback, { - conditions: conds, - options: options - }); - - this._collection.distinct(this._distinct, conds, options, utils.tick(callback)); - - return this; -}; - -/** - * Declare and/or execute this query as an update() operation. By default, - * `update()` only modifies the _first_ document that matches `criteria`. - * - * _All paths passed that are not $atomic operations will become $set ops._ - * - * ####Example - * - * mquery({ _id: id }).update({ title: 'words' }, ...) - * - * becomes - * - * collection.update({ _id: id }, { $set: { title: 'words' }}, ...) - * - * ####Note - * - * Passing an empty object `{}` as the doc will result in a no-op unless the `overwrite` option is passed. Without the `overwrite` option set, the update operation will be ignored and the callback executed without sending the command to MongoDB so as to prevent accidently overwritting documents in the collection. - * - * ####Note - * - * The operation is only executed when a callback is passed. To force execution without a callback (which would be an unsafe write), we must first call update() and then execute it by using the `exec()` method. - * - * var q = mquery(collection).where({ _id: id }); - * q.update({ $set: { name: 'bob' }}).update(); // not executed - * - * var q = mquery(collection).where({ _id: id }); - * q.update({ $set: { name: 'bob' }}).exec(); // executed as unsafe - * - * // keys that are not $atomic ops become $set. - * // this executes the same command as the previous example. - * q.update({ name: 'bob' }).where({ _id: id }).exec(); - * - * var q = mquery(collection).update(); // not executed - * - * // overwriting with empty docs - * var q.where({ _id: id }).setOptions({ overwrite: true }) - * q.update({ }, callback); // executes - * - * // multi update with overwrite to empty doc - * var q = mquery(collection).where({ _id: id }); - * q.setOptions({ multi: true, overwrite: true }) - * q.update({ }); - * q.update(callback); // executed - * - * // multi updates - * mquery() - * .collection(coll) - * .update({ name: /^match/ }, { $set: { arr: [] }}, { multi: true }, callback) - * // more multi updates - * mquery({ }) - * .collection(coll) - * .setOptions({ multi: true }) - * .update({ $set: { arr: [] }}, callback) - * - * // single update by default - * mquery({ email: 'address@example.com' }) - * .collection(coll) - * .update({ $inc: { counter: 1 }}, callback) - * - * // summary - * update(criteria, doc, opts, cb) // executes - * update(criteria, doc, opts) - * update(criteria, doc, cb) // executes - * update(criteria, doc) - * update(doc, cb) // executes - * update(doc) - * update(cb) // executes - * update(true) // executes (unsafe write) - * update() - * - * @param {Object} [criteria] - * @param {Object} [doc] the update command - * @param {Object} [options] - * @param {Function} [callback] - * @return {Query} this - * @api public - */ - -Query.prototype.update = function update(criteria, doc, options, callback) { - var force; - - switch (arguments.length) { - case 3: - if ('function' == typeof options) { - callback = options; - options = undefined; - } - break; - case 2: - if ('function' == typeof doc) { - callback = doc; - doc = criteria; - criteria = undefined; - } - break; - case 1: - switch (typeof criteria) { - case 'function': - callback = criteria; - criteria = options = doc = undefined; - break; - case 'boolean': - // execution with no callback (unsafe write) - force = criteria; - criteria = undefined; - break; - default: - doc = criteria; - criteria = options = undefined; - break; - } - } - - return _update(this, 'update', criteria, doc, options, force, callback); -}; - -/** - * Declare and/or execute this query as an `updateMany()` operation. Identical - * to `update()` except `updateMany()` will update _all_ documents that match - * `criteria`, rather than just the first one. - * - * _All paths passed that are not $atomic operations will become $set ops._ - * - * ####Example - * - * // Update every document whose `title` contains 'test' - * mquery().updateMany({ title: /test/ }, { year: 2017 }) - * - * @param {Object} [criteria] - * @param {Object} [doc] the update command - * @param {Object} [options] - * @param {Function} [callback] - * @return {Query} this - * @api public - */ - -Query.prototype.updateMany = function updateMany(criteria, doc, options, callback) { - var force; - - switch (arguments.length) { - case 3: - if ('function' == typeof options) { - callback = options; - options = undefined; - } - break; - case 2: - if ('function' == typeof doc) { - callback = doc; - doc = criteria; - criteria = undefined; - } - break; - case 1: - switch (typeof criteria) { - case 'function': - callback = criteria; - criteria = options = doc = undefined; - break; - case 'boolean': - // execution with no callback (unsafe write) - force = criteria; - criteria = undefined; - break; - default: - doc = criteria; - criteria = options = undefined; - break; - } - } - - return _update(this, 'updateMany', criteria, doc, options, force, callback); -}; - -/** - * Declare and/or execute this query as an `updateOne()` operation. Identical - * to `update()` except `updateOne()` will _always_ update just one document, - * regardless of the `multi` option. - * - * _All paths passed that are not $atomic operations will become $set ops._ - * - * ####Example - * - * // Update the first document whose `title` contains 'test' - * mquery().updateMany({ title: /test/ }, { year: 2017 }) - * - * @param {Object} [criteria] - * @param {Object} [doc] the update command - * @param {Object} [options] - * @param {Function} [callback] - * @return {Query} this - * @api public - */ - -Query.prototype.updateOne = function updateOne(criteria, doc, options, callback) { - var force; - - switch (arguments.length) { - case 3: - if ('function' == typeof options) { - callback = options; - options = undefined; - } - break; - case 2: - if ('function' == typeof doc) { - callback = doc; - doc = criteria; - criteria = undefined; - } - break; - case 1: - switch (typeof criteria) { - case 'function': - callback = criteria; - criteria = options = doc = undefined; - break; - case 'boolean': - // execution with no callback (unsafe write) - force = criteria; - criteria = undefined; - break; - default: - doc = criteria; - criteria = options = undefined; - break; - } - } - - return _update(this, 'updateOne', criteria, doc, options, force, callback); -}; - -/** - * Declare and/or execute this query as an `replaceOne()` operation. Similar - * to `updateOne()`, except `replaceOne()` is not allowed to use atomic - * modifiers (`$set`, `$push`, etc.). Calling `replaceOne()` will always - * replace the existing doc. - * - * ####Example - * - * // Replace the document with `_id` 1 with `{ _id: 1, year: 2017 }` - * mquery().replaceOne({ _id: 1 }, { year: 2017 }) - * - * @param {Object} [criteria] - * @param {Object} [doc] the update command - * @param {Object} [options] - * @param {Function} [callback] - * @return {Query} this - * @api public - */ - -Query.prototype.replaceOne = function replaceOne(criteria, doc, options, callback) { - var force; - - switch (arguments.length) { - case 3: - if ('function' == typeof options) { - callback = options; - options = undefined; - } - break; - case 2: - if ('function' == typeof doc) { - callback = doc; - doc = criteria; - criteria = undefined; - } - break; - case 1: - switch (typeof criteria) { - case 'function': - callback = criteria; - criteria = options = doc = undefined; - break; - case 'boolean': - // execution with no callback (unsafe write) - force = criteria; - criteria = undefined; - break; - default: - doc = criteria; - criteria = options = undefined; - break; - } - } - - this.setOptions({ overwrite: true }); - return _update(this, 'replaceOne', criteria, doc, options, force, callback); -}; - - -/*! - * Internal helper for update, updateMany, updateOne - */ - -function _update(query, op, criteria, doc, options, force, callback) { - query.op = op; - - if (Query.canMerge(criteria)) { - query.merge(criteria); - } - - if (doc) { - query._mergeUpdate(doc); - } - - if (utils.isObject(options)) { - // { overwrite: true } - query.setOptions(options); - } - - // we are done if we don't have callback and they are - // not forcing an unsafe write. - if (!(force || callback)) { - return query; - } - - if (!query._update || - !query.options.overwrite && 0 === utils.keys(query._update).length) { - callback && utils.soon(callback.bind(null, null, 0)); - return query; - } - - options = query._optionsForExec(); - if (!callback) options.safe = false; - - criteria = query._conditions; - doc = query._updateForExec(); - - debug('update', query._collection.collectionName, criteria, doc, options); - callback = query._wrapCallback(op, callback, { - conditions: criteria, - doc: doc, - options: options - }); - - query._collection[op](criteria, doc, options, utils.tick(callback)); - - return query; -} - -/** - * Declare and/or execute this query as a remove() operation. - * - * ####Example - * - * mquery(collection).remove({ artist: 'Anne Murray' }, callback) - * - * ####Note - * - * The operation is only executed when a callback is passed. To force execution without a callback (which would be an unsafe write), we must first call remove() and then execute it by using the `exec()` method. - * - * // not executed - * var query = mquery(collection).remove({ name: 'Anne Murray' }) - * - * // executed - * mquery(collection).remove({ name: 'Anne Murray' }, callback) - * mquery(collection).remove({ name: 'Anne Murray' }).remove(callback) - * - * // executed without a callback (unsafe write) - * query.exec() - * - * // summary - * query.remove(conds, fn); // executes - * query.remove(conds) - * query.remove(fn) // executes - * query.remove() - * - * @param {Object|Query} [criteria] mongodb selector - * @param {Function} [callback] - * @return {Query} this - * @api public - */ - -Query.prototype.remove = function(criteria, callback) { - this.op = 'remove'; - var force; - - if ('function' === typeof criteria) { - callback = criteria; - criteria = undefined; - } else if (Query.canMerge(criteria)) { - this.merge(criteria); - } else if (true === criteria) { - force = criteria; - criteria = undefined; - } - - if (!(force || callback)) - return this; - - var options = this._optionsForExec(); - if (!callback) options.safe = false; - - var conds = this._conditions; - - debug('remove', this._collection.collectionName, conds, options); - callback = this._wrapCallback('remove', callback, { - conditions: conds, - options: options - }); - - this._collection.remove(conds, options, utils.tick(callback)); - - return this; -}; - -/** - * Declare and/or execute this query as a `deleteOne()` operation. Behaves like - * `remove()`, except for ignores the `justOne` option and always deletes at - * most one document. - * - * ####Example - * - * mquery(collection).deleteOne({ artist: 'Anne Murray' }, callback) - * - * @param {Object|Query} [criteria] mongodb selector - * @param {Function} [callback] - * @return {Query} this - * @api public - */ - -Query.prototype.deleteOne = function(criteria, callback) { - this.op = 'deleteOne'; - var force; - - if ('function' === typeof criteria) { - callback = criteria; - criteria = undefined; - } else if (Query.canMerge(criteria)) { - this.merge(criteria); - } else if (true === criteria) { - force = criteria; - criteria = undefined; - } - - if (!(force || callback)) - return this; - - var options = this._optionsForExec(); - if (!callback) options.safe = false; - delete options.justOne; - - var conds = this._conditions; - - debug('deleteOne', this._collection.collectionName, conds, options); - callback = this._wrapCallback('deleteOne', callback, { - conditions: conds, - options: options - }); - - this._collection.deleteOne(conds, options, utils.tick(callback)); - - return this; -}; - -/** - * Declare and/or execute this query as a `deleteMany()` operation. Behaves like - * `remove()`, except for ignores the `justOne` option and always deletes - * _every_ document that matches `criteria`. - * - * ####Example - * - * mquery(collection).deleteMany({ artist: 'Anne Murray' }, callback) - * - * @param {Object|Query} [criteria] mongodb selector - * @param {Function} [callback] - * @return {Query} this - * @api public - */ - -Query.prototype.deleteMany = function(criteria, callback) { - this.op = 'deleteMany'; - var force; - - if ('function' === typeof criteria) { - callback = criteria; - criteria = undefined; - } else if (Query.canMerge(criteria)) { - this.merge(criteria); - } else if (true === criteria) { - force = criteria; - criteria = undefined; - } - - if (!(force || callback)) - return this; - - var options = this._optionsForExec(); - if (!callback) options.safe = false; - delete options.justOne; - - var conds = this._conditions; - - debug('deleteOne', this._collection.collectionName, conds, options); - callback = this._wrapCallback('deleteOne', callback, { - conditions: conds, - options: options - }); - - this._collection.deleteMany(conds, options, utils.tick(callback)); - - return this; -}; - -/** - * Issues a mongodb [findAndModify](http://www.mongodb.org/display/DOCS/findAndModify+Command) update command. - * - * Finds a matching document, updates it according to the `update` arg, passing any `options`, and returns the found document (if any) to the callback. The query executes immediately if `callback` is passed. - * - * ####Available options - * - * - `new`: bool - true to return the modified document rather than the original. defaults to true - * - `upsert`: bool - creates the object if it doesn't exist. defaults to false. - * - `sort`: if multiple docs are found by the conditions, sets the sort order to choose which doc to update - * - * ####Examples - * - * query.findOneAndUpdate(conditions, update, options, callback) // executes - * query.findOneAndUpdate(conditions, update, options) // returns Query - * query.findOneAndUpdate(conditions, update, callback) // executes - * query.findOneAndUpdate(conditions, update) // returns Query - * query.findOneAndUpdate(update, callback) // returns Query - * query.findOneAndUpdate(update) // returns Query - * query.findOneAndUpdate(callback) // executes - * query.findOneAndUpdate() // returns Query - * - * @param {Object|Query} [query] - * @param {Object} [doc] - * @param {Object} [options] - * @param {Function} [callback] - * @see mongodb http://www.mongodb.org/display/DOCS/findAndModify+Command - * @return {Query} this - * @api public - */ - -Query.prototype.findOneAndUpdate = function(criteria, doc, options, callback) { - this.op = 'findOneAndUpdate'; - this._validate(); - - switch (arguments.length) { - case 3: - if ('function' == typeof options) { - callback = options; - options = {}; - } - break; - case 2: - if ('function' == typeof doc) { - callback = doc; - doc = criteria; - criteria = undefined; - } - options = undefined; - break; - case 1: - if ('function' == typeof criteria) { - callback = criteria; - criteria = options = doc = undefined; - } else { - doc = criteria; - criteria = options = undefined; - } - } - - if (Query.canMerge(criteria)) { - this.merge(criteria); - } - - // apply doc - if (doc) { - this._mergeUpdate(doc); - } - - options && this.setOptions(options); - - if (!callback) return this; - return this._findAndModify('update', callback); -}; - -/** - * Issues a mongodb [findAndModify](http://www.mongodb.org/display/DOCS/findAndModify+Command) remove command. - * - * Finds a matching document, removes it, passing the found document (if any) to the callback. Executes immediately if `callback` is passed. - * - * ####Available options - * - * - `sort`: if multiple docs are found by the conditions, sets the sort order to choose which doc to update - * - * ####Examples - * - * A.where().findOneAndRemove(conditions, options, callback) // executes - * A.where().findOneAndRemove(conditions, options) // return Query - * A.where().findOneAndRemove(conditions, callback) // executes - * A.where().findOneAndRemove(conditions) // returns Query - * A.where().findOneAndRemove(callback) // executes - * A.where().findOneAndRemove() // returns Query - * A.where().findOneAndDelete() // alias of .findOneAndRemove() - * - * @param {Object} [conditions] - * @param {Object} [options] - * @param {Function} [callback] - * @return {Query} this - * @see mongodb http://www.mongodb.org/display/DOCS/findAndModify+Command - * @api public - */ - -Query.prototype.findOneAndRemove = Query.prototype.findOneAndDelete = function(conditions, options, callback) { - this.op = 'findOneAndRemove'; - this._validate(); - - if ('function' == typeof options) { - callback = options; - options = undefined; - } else if ('function' == typeof conditions) { - callback = conditions; - conditions = undefined; - } - - // apply conditions - if (Query.canMerge(conditions)) { - this.merge(conditions); - } - - // apply options - options && this.setOptions(options); - - if (!callback) return this; - - return this._findAndModify('remove', callback); -}; - -/** - * _findAndModify - * - * @param {String} type - either "remove" or "update" - * @param {Function} callback - * @api private - */ - -Query.prototype._findAndModify = function(type, callback) { - assert.equal('function', typeof callback); - - var options = this._optionsForExec(); - var fields; - var doc; - - if ('remove' == type) { - options.remove = true; - } else { - if (!('new' in options)) options.new = true; - if (!('upsert' in options)) options.upsert = false; - - doc = this._updateForExec(); - if (!doc) { - if (options.upsert) { - // still need to do the upsert to empty doc - doc = { $set: {} }; - } else { - return this.findOne(callback); - } - } - } - - fields = this._fieldsForExec(); - if (fields != null) { - if (this.$useProjection) { - options.projection = this._fieldsForExec(); - } else { - options.fields = this._fieldsForExec(); - } - } - - var conds = this._conditions; - - debug('findAndModify', this._collection.collectionName, conds, doc, options); - callback = this._wrapCallback('findAndModify', callback, { - conditions: conds, - doc: doc, - options: options - }); - - this._collection.findAndModify(conds, doc, options, utils.tick(callback)); - - return this; -}; - -/** - * Wrap callback to add tracing - * - * @param {Function} callback - * @param {Object} [queryInfo] - * @api private - */ -Query.prototype._wrapCallback = function(method, callback, queryInfo) { - var traceFunction = this._traceFunction || Query.traceFunction; - - if (traceFunction) { - queryInfo.collectionName = this._collection.collectionName; - - var traceCallback = traceFunction && - traceFunction.call(null, method, queryInfo, this); - - var startTime = new Date().getTime(); - - return function wrapperCallback(err, result) { - if (traceCallback) { - var millis = new Date().getTime() - startTime; - traceCallback.call(null, err, result, millis); - } - - if (callback) { - callback.apply(null, arguments); - } - }; - } - - return callback; -}; - -/** - * Add trace function that gets called when the query is executed. - * The function will be called with (method, queryInfo, query) and - * should return a callback function which will be called - * with (err, result, millis) when the query is complete. - * - * queryInfo is an object containing: { - * collectionName: , - * conditions: , - * options: , - * doc: [document to update, if applicable] - * } - * - * NOTE: Does not trace stream queries. - * - * @param {Function} traceFunction - * @return {Query} this - * @api public - */ -Query.prototype.setTraceFunction = function(traceFunction) { - this._traceFunction = traceFunction; - return this; -}; - -/** - * Executes the query - * - * ####Examples - * - * query.exec(); - * query.exec(callback); - * query.exec('update'); - * query.exec('find', callback); - * - * @param {String|Function} [operation] - * @param {Function} [callback] - * @api public - */ - -Query.prototype.exec = function exec(op, callback) { - switch (typeof op) { - case 'function': - callback = op; - op = null; - break; - case 'string': - this.op = op; - break; - } - - assert.ok(this.op, 'Missing query type: (find, update, etc)'); - - if ('update' == this.op || 'remove' == this.op) { - callback || (callback = true); - } - - var _this = this; - - if ('function' == typeof callback) { - this[this.op](callback); - } else { - return new Query.Promise(function(success, error) { - _this[_this.op](function(err, val) { - if (err) error(err); - else success(val); - success = error = null; - }); - }); - } -}; - -/** - * Returns a thunk which when called runs this.exec() - * - * The thunk receives a callback function which will be - * passed to `this.exec()` - * - * @return {Function} - * @api public - */ - -Query.prototype.thunk = function() { - var _this = this; - return function(cb) { - _this.exec(cb); - }; -}; - -/** - * Executes the query returning a `Promise` which will be - * resolved with either the doc(s) or rejected with the error. - * - * @param {Function} [resolve] - * @param {Function} [reject] - * @return {Promise} - * @api public - */ - -Query.prototype.then = function(resolve, reject) { - var _this = this; - var promise = new Query.Promise(function(success, error) { - _this.exec(function(err, val) { - if (err) error(err); - else success(val); - success = error = null; - }); - }); - return promise.then(resolve, reject); -}; - -/** - * Returns a stream for the given find query. - * - * @throws Error if operation is not a find - * @returns {Stream} Node 0.8 style - */ - -Query.prototype.stream = function(streamOptions) { - if ('find' != this.op) - throw new Error('stream() is only available for find'); - - var conds = this._conditions; - - var options = this._optionsForExec(); - if (this.$useProjection) { - options.projection = this._fieldsForExec(); - } else { - options.fields = this._fieldsForExec(); - } - - debug('stream', this._collection.collectionName, conds, options, streamOptions); - - return this._collection.findStream(conds, options, streamOptions); -}; - -/** - * Determines if field selection has been made. - * - * @return {Boolean} - * @api public - */ - -Query.prototype.selected = function selected() { - return !!(this._fields && Object.keys(this._fields).length > 0); -}; - -/** - * Determines if inclusive field selection has been made. - * - * query.selectedInclusively() // false - * query.select('name') - * query.selectedInclusively() // true - * query.selectedExlusively() // false - * - * @returns {Boolean} - */ - -Query.prototype.selectedInclusively = function selectedInclusively() { - if (!this._fields) return false; - - var keys = Object.keys(this._fields); - if (0 === keys.length) return false; - - for (var i = 0; i < keys.length; ++i) { - var key = keys[i]; - if (0 === this._fields[key]) return false; - if (this._fields[key] && - typeof this._fields[key] === 'object' && - this._fields[key].$meta) { - return false; - } - } - - return true; -}; - -/** - * Determines if exclusive field selection has been made. - * - * query.selectedExlusively() // false - * query.select('-name') - * query.selectedExlusively() // true - * query.selectedInclusively() // false - * - * @returns {Boolean} - */ - -Query.prototype.selectedExclusively = function selectedExclusively() { - if (!this._fields) return false; - - var keys = Object.keys(this._fields); - if (0 === keys.length) return false; - - for (var i = 0; i < keys.length; ++i) { - var key = keys[i]; - if (0 === this._fields[key]) return true; - } - - return false; -}; - -/** - * Merges `doc` with the current update object. - * - * @param {Object} doc - */ - -Query.prototype._mergeUpdate = function(doc) { - if (!this._update) this._update = {}; - if (doc instanceof Query) { - if (doc._update) { - utils.mergeClone(this._update, doc._update); - } - } else { - utils.mergeClone(this._update, doc); - } -}; - -/** - * Returns default options. - * - * @return {Object} - * @api private - */ - -Query.prototype._optionsForExec = function() { - var options = utils.clone(this.options); - return options; -}; - -/** - * Returns fields selection for this query. - * - * @return {Object} - * @api private - */ - -Query.prototype._fieldsForExec = function() { - return utils.clone(this._fields); -}; - -/** - * Return an update document with corrected $set operations. - * - * @api private - */ - -Query.prototype._updateForExec = function() { - var update = utils.clone(this._update), - ops = utils.keys(update), - i = ops.length, - ret = {}; - - while (i--) { - var op = ops[i]; - - if (this.options.overwrite) { - ret[op] = update[op]; - continue; - } - - if ('$' !== op[0]) { - // fix up $set sugar - if (!ret.$set) { - if (update.$set) { - ret.$set = update.$set; - } else { - ret.$set = {}; - } - } - ret.$set[op] = update[op]; - ops.splice(i, 1); - if (!~ops.indexOf('$set')) ops.push('$set'); - } else if ('$set' === op) { - if (!ret.$set) { - ret[op] = update[op]; - } - } else { - ret[op] = update[op]; - } - } - - this._compiledUpdate = ret; - return ret; -}; - -/** - * Make sure _path is set. - * - * @parmam {String} method - */ - -Query.prototype._ensurePath = function(method) { - if (!this._path) { - var msg = method + '() must be used after where() ' - + 'when called with these arguments'; - throw new Error(msg); - } -}; - -/*! - * Permissions - */ - -Query.permissions = require('./permissions'); - -Query._isPermitted = function(a, b) { - var denied = Query.permissions[b]; - if (!denied) return true; - return true !== denied[a]; -}; - -Query.prototype._validate = function(action) { - var fail; - var validator; - - if (undefined === action) { - - validator = Query.permissions[this.op]; - if ('function' != typeof validator) return true; - - fail = validator(this); - - } else if (!Query._isPermitted(action, this.op)) { - fail = action; - } - - if (fail) { - throw new Error(fail + ' cannot be used with ' + this.op); - } -}; - -/** - * Determines if `conds` can be merged using `mquery().merge()` - * - * @param {Object} conds - * @return {Boolean} - */ - -Query.canMerge = function(conds) { - return conds instanceof Query || utils.isObject(conds); -}; - -/** - * Set a trace function that will get called whenever a - * query is executed. - * - * See `setTraceFunction()` for details. - * - * @param {Object} conds - * @return {Boolean} - */ -Query.setGlobalTraceFunction = function(traceFunction) { - Query.traceFunction = traceFunction; -}; - -/*! - * Exports. - */ - -Query.utils = utils; -Query.env = require('./env'); -Query.Collection = require('./collection'); -Query.BaseCollection = require('./collection/collection'); -Query.Promise = require('bluebird'); -module.exports = exports = Query; - -// TODO -// test utils diff --git a/node_modules/mquery/lib/permissions.js b/node_modules/mquery/lib/permissions.js deleted file mode 100644 index c306f3a..0000000 --- a/node_modules/mquery/lib/permissions.js +++ /dev/null @@ -1,88 +0,0 @@ -'use strict'; - -var denied = exports; - -denied.distinct = function(self) { - if (self._fields && Object.keys(self._fields).length > 0) { - return 'field selection and slice'; - } - - var keys = Object.keys(denied.distinct); - var err; - - keys.every(function(option) { - if (self.options[option]) { - err = option; - return false; - } - return true; - }); - - return err; -}; -denied.distinct.select = -denied.distinct.slice = -denied.distinct.sort = -denied.distinct.limit = -denied.distinct.skip = -denied.distinct.batchSize = -denied.distinct.comment = -denied.distinct.maxScan = -denied.distinct.snapshot = -denied.distinct.hint = -denied.distinct.tailable = true; - - -// aggregation integration - - -denied.findOneAndUpdate = -denied.findOneAndRemove = function(self) { - var keys = Object.keys(denied.findOneAndUpdate); - var err; - - keys.every(function(option) { - if (self.options[option]) { - err = option; - return false; - } - return true; - }); - - return err; -}; -denied.findOneAndUpdate.limit = -denied.findOneAndUpdate.skip = -denied.findOneAndUpdate.batchSize = -denied.findOneAndUpdate.maxScan = -denied.findOneAndUpdate.snapshot = -denied.findOneAndUpdate.hint = -denied.findOneAndUpdate.tailable = -denied.findOneAndUpdate.comment = true; - - -denied.count = function(self) { - if (self._fields && Object.keys(self._fields).length > 0) { - return 'field selection and slice'; - } - - var keys = Object.keys(denied.count); - var err; - - keys.every(function(option) { - if (self.options[option]) { - err = option; - return false; - } - return true; - }); - - return err; -}; - -denied.count.slice = -denied.count.batchSize = -denied.count.comment = -denied.count.maxScan = -denied.count.snapshot = -denied.count.tailable = true; diff --git a/node_modules/mquery/lib/utils.js b/node_modules/mquery/lib/utils.js deleted file mode 100644 index ef51712..0000000 --- a/node_modules/mquery/lib/utils.js +++ /dev/null @@ -1,356 +0,0 @@ -'use strict'; - -/*! - * Module dependencies. - */ - -var Buffer = require('safe-buffer').Buffer; -var RegExpClone = require('regexp-clone'); - -/** - * Clones objects - * - * @param {Object} obj the object to clone - * @param {Object} options - * @return {Object} the cloned object - * @api private - */ - -var clone = exports.clone = function clone(obj, options) { - if (obj === undefined || obj === null) - return obj; - - if (Array.isArray(obj)) - return exports.cloneArray(obj, options); - - if (obj.constructor) { - if (/ObjectI[dD]$/.test(obj.constructor.name)) { - return 'function' == typeof obj.clone - ? obj.clone() - : new obj.constructor(obj.id); - } - - if (obj.constructor.name === 'ReadPreference') { - return new obj.constructor(obj.mode, clone(obj.tags, options)); - } - - if ('Binary' == obj._bsontype && obj.buffer && obj.value) { - return 'function' == typeof obj.clone - ? obj.clone() - : new obj.constructor(obj.value(true), obj.sub_type); - } - - if ('Date' === obj.constructor.name || 'Function' === obj.constructor.name) - return new obj.constructor(+obj); - - if ('RegExp' === obj.constructor.name) - return RegExpClone(obj); - - if ('Buffer' === obj.constructor.name) - return exports.cloneBuffer(obj); - } - - if (isObject(obj)) - return exports.cloneObject(obj, options); - - if (obj.valueOf) - return obj.valueOf(); -}; - -/*! - * ignore - */ - -exports.cloneObject = function cloneObject(obj, options) { - var minimize = options && options.minimize; - var ret = {}; - var hasKeys; - var val; - var k; - - for (k in obj) { - val = clone(obj[k], options); - - if (!minimize || ('undefined' !== typeof val)) { - hasKeys || (hasKeys = true); - ret[k] = val; - } - } - - return minimize - ? hasKeys && ret - : ret; -}; - -exports.cloneArray = function cloneArray(arr, options) { - var ret = []; - for (var i = 0, l = arr.length; i < l; i++) - ret.push(clone(arr[i], options)); - return ret; -}; - -/** - * process.nextTick helper. - * - * Wraps the given `callback` in a try/catch. If an error is - * caught it will be thrown on nextTick. - * - * node-mongodb-native had a habit of state corruption when - * an error was immediately thrown from within a collection - * method (find, update, etc) callback. - * - * @param {Function} [callback] - * @api private - */ - -exports.tick = function tick(callback) { - if ('function' !== typeof callback) return; - return function() { - // callbacks should always be fired on the next - // turn of the event loop. A side benefit is - // errors thrown from executing the callback - // will not cause drivers state to be corrupted - // which has historically been a problem. - var args = arguments; - soon(function() { - callback.apply(this, args); - }); - }; -}; - -/** - * Merges `from` into `to` without overwriting existing properties. - * - * @param {Object} to - * @param {Object} from - * @api private - */ - -exports.merge = function merge(to, from) { - var keys = Object.keys(from), - i = keys.length, - key; - - while (i--) { - key = keys[i]; - if ('undefined' === typeof to[key]) { - to[key] = from[key]; - } else { - if (exports.isObject(from[key])) { - merge(to[key], from[key]); - } else { - to[key] = from[key]; - } - } - } -}; - -/** - * Same as merge but clones the assigned values. - * - * @param {Object} to - * @param {Object} from - * @api private - */ - -exports.mergeClone = function mergeClone(to, from) { - var keys = Object.keys(from), - i = keys.length, - key; - - while (i--) { - key = keys[i]; - if ('undefined' === typeof to[key]) { - to[key] = clone(from[key]); - } else { - if (exports.isObject(from[key])) { - mergeClone(to[key], from[key]); - } else { - to[key] = clone(from[key]); - } - } - } -}; - -/** - * Read pref helper (mongo 2.2 drivers support this) - * - * Allows using aliases instead of full preference names: - * - * p primary - * pp primaryPreferred - * s secondary - * sp secondaryPreferred - * n nearest - * - * @param {String} pref - */ - -exports.readPref = function readPref(pref) { - switch (pref) { - case 'p': - pref = 'primary'; - break; - case 'pp': - pref = 'primaryPreferred'; - break; - case 's': - pref = 'secondary'; - break; - case 'sp': - pref = 'secondaryPreferred'; - break; - case 'n': - pref = 'nearest'; - break; - } - - return pref; -}; - - -/** - * Read Concern helper (mongo 3.2 drivers support this) - * - * Allows using string to specify read concern level: - * - * local 3.2+ - * available 3.6+ - * majority 3.2+ - * linearizable 3.4+ - * snapshot 4.0+ - * - * @param {String|Object} concern - */ - -exports.readConcern = function readConcern(concern) { - if ('string' === typeof concern) { - switch (concern) { - case 'l': - concern = 'local'; - break; - case 'a': - concern = 'available'; - break; - case 'm': - concern = 'majority'; - break; - case 'lz': - concern = 'linearizable'; - break; - case 's': - concern = 'snapshot'; - break; - } - concern = { level: concern }; - } - return concern; -}; - -/** - * Object.prototype.toString.call helper - */ - -var _toString = Object.prototype.toString; -exports.toString = function(arg) { - return _toString.call(arg); -}; - -/** - * Determines if `arg` is an object. - * - * @param {Object|Array|String|Function|RegExp|any} arg - * @return {Boolean} - */ - -var isObject = exports.isObject = function(arg) { - return '[object Object]' == exports.toString(arg); -}; - -/** - * Determines if `arg` is an array. - * - * @param {Object} - * @return {Boolean} - * @see nodejs utils - */ - -exports.isArray = function(arg) { - return Array.isArray(arg) || - 'object' == typeof arg && '[object Array]' == exports.toString(arg); -}; - -/** - * Object.keys helper - */ - -exports.keys = Object.keys || function(obj) { - var keys = []; - for (var k in obj) if (obj.hasOwnProperty(k)) { - keys.push(k); - } - return keys; -}; - -/** - * Basic Object.create polyfill. - * Only one argument is supported. - * - * Based on https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/create - */ - -exports.create = 'function' == typeof Object.create - ? Object.create - : create; - -function create(proto) { - if (arguments.length > 1) { - throw new Error('Adding properties is not supported'); - } - - function F() {} - F.prototype = proto; - return new F; -} - -/** - * inheritance - */ - -exports.inherits = function(ctor, superCtor) { - ctor.prototype = exports.create(superCtor.prototype); - ctor.prototype.constructor = ctor; -}; - -/** - * nextTick helper - * compat with node 0.10 which behaves differently than previous versions - */ - -var soon = exports.soon = 'function' == typeof setImmediate - ? setImmediate - : process.nextTick; - -/** - * Clones the contents of a buffer. - * - * @param {Buffer} buff - * @return {Buffer} - */ - -exports.cloneBuffer = function(buff) { - var dupe = Buffer.alloc(buff.length); - buff.copy(dupe, 0, 0, buff.length); - return dupe; -}; - -/** - * Check if this object is an arguments object - * - * @param {Any} v - * @return {Boolean} - */ - -exports.isArgumentsObject = function(v) { - return Object.prototype.toString.call(v) === '[object Arguments]'; -}; diff --git a/node_modules/mquery/node_modules/debug/.coveralls.yml b/node_modules/mquery/node_modules/debug/.coveralls.yml deleted file mode 100644 index 20a7068..0000000 --- a/node_modules/mquery/node_modules/debug/.coveralls.yml +++ /dev/null @@ -1 +0,0 @@ -repo_token: SIAeZjKYlHK74rbcFvNHMUzjRiMpflxve diff --git a/node_modules/mquery/node_modules/debug/.eslintrc b/node_modules/mquery/node_modules/debug/.eslintrc deleted file mode 100644 index 146371e..0000000 --- a/node_modules/mquery/node_modules/debug/.eslintrc +++ /dev/null @@ -1,14 +0,0 @@ -{ - "env": { - "browser": true, - "node": true - }, - "globals": { - "chrome": true - }, - "rules": { - "no-console": 0, - "no-empty": [1, { "allowEmptyCatch": true }] - }, - "extends": "eslint:recommended" -} diff --git a/node_modules/mquery/node_modules/debug/.npmignore b/node_modules/mquery/node_modules/debug/.npmignore deleted file mode 100644 index 5f60eec..0000000 --- a/node_modules/mquery/node_modules/debug/.npmignore +++ /dev/null @@ -1,9 +0,0 @@ -support -test -examples -example -*.sock -dist -yarn.lock -coverage -bower.json diff --git a/node_modules/mquery/node_modules/debug/.travis.yml b/node_modules/mquery/node_modules/debug/.travis.yml deleted file mode 100644 index a764300..0000000 --- a/node_modules/mquery/node_modules/debug/.travis.yml +++ /dev/null @@ -1,20 +0,0 @@ -sudo: false - -language: node_js - -node_js: - - "4" - - "6" - - "8" - -install: - - make install - -script: - - make lint - - make test - -matrix: - include: - - node_js: '8' - env: BROWSER=1 diff --git a/node_modules/mquery/node_modules/debug/CHANGELOG.md b/node_modules/mquery/node_modules/debug/CHANGELOG.md deleted file mode 100644 index 820d21e..0000000 --- a/node_modules/mquery/node_modules/debug/CHANGELOG.md +++ /dev/null @@ -1,395 +0,0 @@ - -3.1.0 / 2017-09-26 -================== - - * Add `DEBUG_HIDE_DATE` env var (#486) - * Remove ReDoS regexp in %o formatter (#504) - * Remove "component" from package.json - * Remove `component.json` - * Ignore package-lock.json - * Examples: fix colors printout - * Fix: browser detection - * Fix: spelling mistake (#496, @EdwardBetts) - -3.0.1 / 2017-08-24 -================== - - * Fix: Disable colors in Edge and Internet Explorer (#489) - -3.0.0 / 2017-08-08 -================== - - * Breaking: Remove DEBUG_FD (#406) - * Breaking: Use `Date#toISOString()` instead to `Date#toUTCString()` when output is not a TTY (#418) - * Breaking: Make millisecond timer namespace specific and allow 'always enabled' output (#408) - * Addition: document `enabled` flag (#465) - * Addition: add 256 colors mode (#481) - * Addition: `enabled()` updates existing debug instances, add `destroy()` function (#440) - * Update: component: update "ms" to v2.0.0 - * Update: separate the Node and Browser tests in Travis-CI - * Update: refactor Readme, fixed documentation, added "Namespace Colors" section, redid screenshots - * Update: separate Node.js and web browser examples for organization - * Update: update "browserify" to v14.4.0 - * Fix: fix Readme typo (#473) - -2.6.9 / 2017-09-22 -================== - - * remove ReDoS regexp in %o formatter (#504) - -2.6.8 / 2017-05-18 -================== - - * Fix: Check for undefined on browser globals (#462, @marbemac) - -2.6.7 / 2017-05-16 -================== - - * Fix: Update ms to 2.0.0 to fix regular expression denial of service vulnerability (#458, @hubdotcom) - * Fix: Inline extend function in node implementation (#452, @dougwilson) - * Docs: Fix typo (#455, @msasad) - -2.6.5 / 2017-04-27 -================== - - * Fix: null reference check on window.documentElement.style.WebkitAppearance (#447, @thebigredgeek) - * Misc: clean up browser reference checks (#447, @thebigredgeek) - * Misc: add npm-debug.log to .gitignore (@thebigredgeek) - - -2.6.4 / 2017-04-20 -================== - - * Fix: bug that would occur if process.env.DEBUG is a non-string value. (#444, @LucianBuzzo) - * Chore: ignore bower.json in npm installations. (#437, @joaovieira) - * Misc: update "ms" to v0.7.3 (@tootallnate) - -2.6.3 / 2017-03-13 -================== - - * Fix: Electron reference to `process.env.DEBUG` (#431, @paulcbetts) - * Docs: Changelog fix (@thebigredgeek) - -2.6.2 / 2017-03-10 -================== - - * Fix: DEBUG_MAX_ARRAY_LENGTH (#420, @slavaGanzin) - * Docs: Add backers and sponsors from Open Collective (#422, @piamancini) - * Docs: Add Slackin invite badge (@tootallnate) - -2.6.1 / 2017-02-10 -================== - - * Fix: Module's `export default` syntax fix for IE8 `Expected identifier` error - * Fix: Whitelist DEBUG_FD for values 1 and 2 only (#415, @pi0) - * Fix: IE8 "Expected identifier" error (#414, @vgoma) - * Fix: Namespaces would not disable once enabled (#409, @musikov) - -2.6.0 / 2016-12-28 -================== - - * Fix: added better null pointer checks for browser useColors (@thebigredgeek) - * Improvement: removed explicit `window.debug` export (#404, @tootallnate) - * Improvement: deprecated `DEBUG_FD` environment variable (#405, @tootallnate) - -2.5.2 / 2016-12-25 -================== - - * Fix: reference error on window within webworkers (#393, @KlausTrainer) - * Docs: fixed README typo (#391, @lurch) - * Docs: added notice about v3 api discussion (@thebigredgeek) - -2.5.1 / 2016-12-20 -================== - - * Fix: babel-core compatibility - -2.5.0 / 2016-12-20 -================== - - * Fix: wrong reference in bower file (@thebigredgeek) - * Fix: webworker compatibility (@thebigredgeek) - * Fix: output formatting issue (#388, @kribblo) - * Fix: babel-loader compatibility (#383, @escwald) - * Misc: removed built asset from repo and publications (@thebigredgeek) - * Misc: moved source files to /src (#378, @yamikuronue) - * Test: added karma integration and replaced babel with browserify for browser tests (#378, @yamikuronue) - * Test: coveralls integration (#378, @yamikuronue) - * Docs: simplified language in the opening paragraph (#373, @yamikuronue) - -2.4.5 / 2016-12-17 -================== - - * Fix: `navigator` undefined in Rhino (#376, @jochenberger) - * Fix: custom log function (#379, @hsiliev) - * Improvement: bit of cleanup + linting fixes (@thebigredgeek) - * Improvement: rm non-maintainted `dist/` dir (#375, @freewil) - * Docs: simplified language in the opening paragraph. (#373, @yamikuronue) - -2.4.4 / 2016-12-14 -================== - - * Fix: work around debug being loaded in preload scripts for electron (#368, @paulcbetts) - -2.4.3 / 2016-12-14 -================== - - * Fix: navigation.userAgent error for react native (#364, @escwald) - -2.4.2 / 2016-12-14 -================== - - * Fix: browser colors (#367, @tootallnate) - * Misc: travis ci integration (@thebigredgeek) - * Misc: added linting and testing boilerplate with sanity check (@thebigredgeek) - -2.4.1 / 2016-12-13 -================== - - * Fix: typo that broke the package (#356) - -2.4.0 / 2016-12-13 -================== - - * Fix: bower.json references unbuilt src entry point (#342, @justmatt) - * Fix: revert "handle regex special characters" (@tootallnate) - * Feature: configurable util.inspect()`options for NodeJS (#327, @tootallnate) - * Feature: %O`(big O) pretty-prints objects (#322, @tootallnate) - * Improvement: allow colors in workers (#335, @botverse) - * Improvement: use same color for same namespace. (#338, @lchenay) - -2.3.3 / 2016-11-09 -================== - - * Fix: Catch `JSON.stringify()` errors (#195, Jovan Alleyne) - * Fix: Returning `localStorage` saved values (#331, Levi Thomason) - * Improvement: Don't create an empty object when no `process` (Nathan Rajlich) - -2.3.2 / 2016-11-09 -================== - - * Fix: be super-safe in index.js as well (@TooTallNate) - * Fix: should check whether process exists (Tom Newby) - -2.3.1 / 2016-11-09 -================== - - * Fix: Added electron compatibility (#324, @paulcbetts) - * Improvement: Added performance optimizations (@tootallnate) - * Readme: Corrected PowerShell environment variable example (#252, @gimre) - * Misc: Removed yarn lock file from source control (#321, @fengmk2) - -2.3.0 / 2016-11-07 -================== - - * Fix: Consistent placement of ms diff at end of output (#215, @gorangajic) - * Fix: Escaping of regex special characters in namespace strings (#250, @zacronos) - * Fix: Fixed bug causing crash on react-native (#282, @vkarpov15) - * Feature: Enabled ES6+ compatible import via default export (#212 @bucaran) - * Feature: Added %O formatter to reflect Chrome's console.log capability (#279, @oncletom) - * Package: Update "ms" to 0.7.2 (#315, @DevSide) - * Package: removed superfluous version property from bower.json (#207 @kkirsche) - * Readme: fix USE_COLORS to DEBUG_COLORS - * Readme: Doc fixes for format string sugar (#269, @mlucool) - * Readme: Updated docs for DEBUG_FD and DEBUG_COLORS environment variables (#232, @mattlyons0) - * Readme: doc fixes for PowerShell (#271 #243, @exoticknight @unreadable) - * Readme: better docs for browser support (#224, @matthewmueller) - * Tooling: Added yarn integration for development (#317, @thebigredgeek) - * Misc: Renamed History.md to CHANGELOG.md (@thebigredgeek) - * Misc: Added license file (#226 #274, @CantemoInternal @sdaitzman) - * Misc: Updated contributors (@thebigredgeek) - -2.2.0 / 2015-05-09 -================== - - * package: update "ms" to v0.7.1 (#202, @dougwilson) - * README: add logging to file example (#193, @DanielOchoa) - * README: fixed a typo (#191, @amir-s) - * browser: expose `storage` (#190, @stephenmathieson) - * Makefile: add a `distclean` target (#189, @stephenmathieson) - -2.1.3 / 2015-03-13 -================== - - * Updated stdout/stderr example (#186) - * Updated example/stdout.js to match debug current behaviour - * Renamed example/stderr.js to stdout.js - * Update Readme.md (#184) - * replace high intensity foreground color for bold (#182, #183) - -2.1.2 / 2015-03-01 -================== - - * dist: recompile - * update "ms" to v0.7.0 - * package: update "browserify" to v9.0.3 - * component: fix "ms.js" repo location - * changed bower package name - * updated documentation about using debug in a browser - * fix: security error on safari (#167, #168, @yields) - -2.1.1 / 2014-12-29 -================== - - * browser: use `typeof` to check for `console` existence - * browser: check for `console.log` truthiness (fix IE 8/9) - * browser: add support for Chrome apps - * Readme: added Windows usage remarks - * Add `bower.json` to properly support bower install - -2.1.0 / 2014-10-15 -================== - - * node: implement `DEBUG_FD` env variable support - * package: update "browserify" to v6.1.0 - * package: add "license" field to package.json (#135, @panuhorsmalahti) - -2.0.0 / 2014-09-01 -================== - - * package: update "browserify" to v5.11.0 - * node: use stderr rather than stdout for logging (#29, @stephenmathieson) - -1.0.4 / 2014-07-15 -================== - - * dist: recompile - * example: remove `console.info()` log usage - * example: add "Content-Type" UTF-8 header to browser example - * browser: place %c marker after the space character - * browser: reset the "content" color via `color: inherit` - * browser: add colors support for Firefox >= v31 - * debug: prefer an instance `log()` function over the global one (#119) - * Readme: update documentation about styled console logs for FF v31 (#116, @wryk) - -1.0.3 / 2014-07-09 -================== - - * Add support for multiple wildcards in namespaces (#122, @seegno) - * browser: fix lint - -1.0.2 / 2014-06-10 -================== - - * browser: update color palette (#113, @gscottolson) - * common: make console logging function configurable (#108, @timoxley) - * node: fix %o colors on old node <= 0.8.x - * Makefile: find node path using shell/which (#109, @timoxley) - -1.0.1 / 2014-06-06 -================== - - * browser: use `removeItem()` to clear localStorage - * browser, node: don't set DEBUG if namespaces is undefined (#107, @leedm777) - * package: add "contributors" section - * node: fix comment typo - * README: list authors - -1.0.0 / 2014-06-04 -================== - - * make ms diff be global, not be scope - * debug: ignore empty strings in enable() - * node: make DEBUG_COLORS able to disable coloring - * *: export the `colors` array - * npmignore: don't publish the `dist` dir - * Makefile: refactor to use browserify - * package: add "browserify" as a dev dependency - * Readme: add Web Inspector Colors section - * node: reset terminal color for the debug content - * node: map "%o" to `util.inspect()` - * browser: map "%j" to `JSON.stringify()` - * debug: add custom "formatters" - * debug: use "ms" module for humanizing the diff - * Readme: add "bash" syntax highlighting - * browser: add Firebug color support - * browser: add colors for WebKit browsers - * node: apply log to `console` - * rewrite: abstract common logic for Node & browsers - * add .jshintrc file - -0.8.1 / 2014-04-14 -================== - - * package: re-add the "component" section - -0.8.0 / 2014-03-30 -================== - - * add `enable()` method for nodejs. Closes #27 - * change from stderr to stdout - * remove unnecessary index.js file - -0.7.4 / 2013-11-13 -================== - - * remove "browserify" key from package.json (fixes something in browserify) - -0.7.3 / 2013-10-30 -================== - - * fix: catch localStorage security error when cookies are blocked (Chrome) - * add debug(err) support. Closes #46 - * add .browser prop to package.json. Closes #42 - -0.7.2 / 2013-02-06 -================== - - * fix package.json - * fix: Mobile Safari (private mode) is broken with debug - * fix: Use unicode to send escape character to shell instead of octal to work with strict mode javascript - -0.7.1 / 2013-02-05 -================== - - * add repository URL to package.json - * add DEBUG_COLORED to force colored output - * add browserify support - * fix component. Closes #24 - -0.7.0 / 2012-05-04 -================== - - * Added .component to package.json - * Added debug.component.js build - -0.6.0 / 2012-03-16 -================== - - * Added support for "-" prefix in DEBUG [Vinay Pulim] - * Added `.enabled` flag to the node version [TooTallNate] - -0.5.0 / 2012-02-02 -================== - - * Added: humanize diffs. Closes #8 - * Added `debug.disable()` to the CS variant - * Removed padding. Closes #10 - * Fixed: persist client-side variant again. Closes #9 - -0.4.0 / 2012-02-01 -================== - - * Added browser variant support for older browsers [TooTallNate] - * Added `debug.enable('project:*')` to browser variant [TooTallNate] - * Added padding to diff (moved it to the right) - -0.3.0 / 2012-01-26 -================== - - * Added millisecond diff when isatty, otherwise UTC string - -0.2.0 / 2012-01-22 -================== - - * Added wildcard support - -0.1.0 / 2011-12-02 -================== - - * Added: remove colors unless stderr isatty [TooTallNate] - -0.0.1 / 2010-01-03 -================== - - * Initial release diff --git a/node_modules/mquery/node_modules/debug/LICENSE b/node_modules/mquery/node_modules/debug/LICENSE deleted file mode 100644 index 658c933..0000000 --- a/node_modules/mquery/node_modules/debug/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -(The MIT License) - -Copyright (c) 2014 TJ Holowaychuk - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software -and associated documentation files (the 'Software'), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT -LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/node_modules/mquery/node_modules/debug/Makefile b/node_modules/mquery/node_modules/debug/Makefile deleted file mode 100644 index 3ddd136..0000000 --- a/node_modules/mquery/node_modules/debug/Makefile +++ /dev/null @@ -1,58 +0,0 @@ -# get Makefile directory name: http://stackoverflow.com/a/5982798/376773 -THIS_MAKEFILE_PATH:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) -THIS_DIR:=$(shell cd $(dir $(THIS_MAKEFILE_PATH));pwd) - -# BIN directory -BIN := $(THIS_DIR)/node_modules/.bin - -# Path -PATH := node_modules/.bin:$(PATH) -SHELL := /bin/bash - -# applications -NODE ?= $(shell which node) -YARN ?= $(shell which yarn) -PKG ?= $(if $(YARN),$(YARN),$(NODE) $(shell which npm)) -BROWSERIFY ?= $(NODE) $(BIN)/browserify - -install: node_modules - -browser: dist/debug.js - -node_modules: package.json - @NODE_ENV= $(PKG) install - @touch node_modules - -dist/debug.js: src/*.js node_modules - @mkdir -p dist - @$(BROWSERIFY) \ - --standalone debug \ - . > dist/debug.js - -lint: - @eslint *.js src/*.js - -test-node: - @istanbul cover node_modules/mocha/bin/_mocha -- test/**.js - @cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js - -test-browser: - @$(MAKE) browser - @karma start --single-run - -test-all: - @concurrently \ - "make test-node" \ - "make test-browser" - -test: - @if [ "x$(BROWSER)" = "x" ]; then \ - $(MAKE) test-node; \ - else \ - $(MAKE) test-browser; \ - fi - -clean: - rimraf dist coverage - -.PHONY: browser install clean lint test test-all test-node test-browser diff --git a/node_modules/mquery/node_modules/debug/README.md b/node_modules/mquery/node_modules/debug/README.md deleted file mode 100644 index 8e754d1..0000000 --- a/node_modules/mquery/node_modules/debug/README.md +++ /dev/null @@ -1,368 +0,0 @@ -# debug -[![Build Status](https://travis-ci.org/visionmedia/debug.svg?branch=master)](https://travis-ci.org/visionmedia/debug) [![Coverage Status](https://coveralls.io/repos/github/visionmedia/debug/badge.svg?branch=master)](https://coveralls.io/github/visionmedia/debug?branch=master) [![Slack](https://visionmedia-community-slackin.now.sh/badge.svg)](https://visionmedia-community-slackin.now.sh/) [![OpenCollective](https://opencollective.com/debug/backers/badge.svg)](#backers) -[![OpenCollective](https://opencollective.com/debug/sponsors/badge.svg)](#sponsors) - - - -A tiny JavaScript debugging utility modelled after Node.js core's debugging -technique. Works in Node.js and web browsers. - -## Installation - -```bash -$ npm install debug -``` - -## Usage - -`debug` exposes a function; simply pass this function the name of your module, and it will return a decorated version of `console.error` for you to pass debug statements to. This will allow you to toggle the debug output for different parts of your module as well as the module as a whole. - -Example [_app.js_](./examples/node/app.js): - -```js -var debug = require('debug')('http') - , http = require('http') - , name = 'My App'; - -// fake app - -debug('booting %o', name); - -http.createServer(function(req, res){ - debug(req.method + ' ' + req.url); - res.end('hello\n'); -}).listen(3000, function(){ - debug('listening'); -}); - -// fake worker of some kind - -require('./worker'); -``` - -Example [_worker.js_](./examples/node/worker.js): - -```js -var a = require('debug')('worker:a') - , b = require('debug')('worker:b'); - -function work() { - a('doing lots of uninteresting work'); - setTimeout(work, Math.random() * 1000); -} - -work(); - -function workb() { - b('doing some work'); - setTimeout(workb, Math.random() * 2000); -} - -workb(); -``` - -The `DEBUG` environment variable is then used to enable these based on space or -comma-delimited names. - -Here are some examples: - -screen shot 2017-08-08 at 12 53 04 pm -screen shot 2017-08-08 at 12 53 38 pm -screen shot 2017-08-08 at 12 53 25 pm - -#### Windows note - -On Windows the environment variable is set using the `set` command. - -```cmd -set DEBUG=*,-not_this -``` - -Note that PowerShell uses different syntax to set environment variables. - -```cmd -$env:DEBUG = "*,-not_this" -``` - -Then, run the program to be debugged as usual. - - -## Namespace Colors - -Every debug instance has a color generated for it based on its namespace name. -This helps when visually parsing the debug output to identify which debug instance -a debug line belongs to. - -#### Node.js - -In Node.js, colors are enabled when stderr is a TTY. You also _should_ install -the [`supports-color`](https://npmjs.org/supports-color) module alongside debug, -otherwise debug will only use a small handful of basic colors. - - - -#### Web Browser - -Colors are also enabled on "Web Inspectors" that understand the `%c` formatting -option. These are WebKit web inspectors, Firefox ([since version -31](https://hacks.mozilla.org/2014/05/editable-box-model-multiple-selection-sublime-text-keys-much-more-firefox-developer-tools-episode-31/)) -and the Firebug plugin for Firefox (any version). - - - - -## Millisecond diff - -When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls. - - - -When stdout is not a TTY, `Date#toISOString()` is used, making it more useful for logging the debug information as shown below: - - - - -## Conventions - -If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser". If you append a "*" to the end of your name, it will always be enabled regardless of the setting of the DEBUG environment variable. You can then use it for normal output as well as debug output. - -## Wildcards - -The `*` character may be used as a wildcard. Suppose for example your library has -debuggers named "connect:bodyParser", "connect:compress", "connect:session", -instead of listing all three with -`DEBUG=connect:bodyParser,connect:compress,connect:session`, you may simply do -`DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`. - -You can also exclude specific debuggers by prefixing them with a "-" character. -For example, `DEBUG=*,-connect:*` would include all debuggers except those -starting with "connect:". - -## Environment Variables - -When running through Node.js, you can set a few environment variables that will -change the behavior of the debug logging: - -| Name | Purpose | -|-----------|-------------------------------------------------| -| `DEBUG` | Enables/disables specific debugging namespaces. | -| `DEBUG_HIDE_DATE` | Hide date from debug output (non-TTY). | -| `DEBUG_COLORS`| Whether or not to use colors in the debug output. | -| `DEBUG_DEPTH` | Object inspection depth. | -| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. | - - -__Note:__ The environment variables beginning with `DEBUG_` end up being -converted into an Options object that gets used with `%o`/`%O` formatters. -See the Node.js documentation for -[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options) -for the complete list. - -## Formatters - -Debug uses [printf-style](https://wikipedia.org/wiki/Printf_format_string) formatting. -Below are the officially supported formatters: - -| Formatter | Representation | -|-----------|----------------| -| `%O` | Pretty-print an Object on multiple lines. | -| `%o` | Pretty-print an Object all on a single line. | -| `%s` | String. | -| `%d` | Number (both integer and float). | -| `%j` | JSON. Replaced with the string '[Circular]' if the argument contains circular references. | -| `%%` | Single percent sign ('%'). This does not consume an argument. | - - -### Custom formatters - -You can add custom formatters by extending the `debug.formatters` object. -For example, if you wanted to add support for rendering a Buffer as hex with -`%h`, you could do something like: - -```js -const createDebug = require('debug') -createDebug.formatters.h = (v) => { - return v.toString('hex') -} - -// …elsewhere -const debug = createDebug('foo') -debug('this is hex: %h', new Buffer('hello world')) -// foo this is hex: 68656c6c6f20776f726c6421 +0ms -``` - - -## Browser Support - -You can build a browser-ready script using [browserify](https://github.com/substack/node-browserify), -or just use the [browserify-as-a-service](https://wzrd.in/) [build](https://wzrd.in/standalone/debug@latest), -if you don't want to build it yourself. - -Debug's enable state is currently persisted by `localStorage`. -Consider the situation shown below where you have `worker:a` and `worker:b`, -and wish to debug both. You can enable this using `localStorage.debug`: - -```js -localStorage.debug = 'worker:*' -``` - -And then refresh the page. - -```js -a = debug('worker:a'); -b = debug('worker:b'); - -setInterval(function(){ - a('doing some work'); -}, 1000); - -setInterval(function(){ - b('doing some work'); -}, 1200); -``` - - -## Output streams - - By default `debug` will log to stderr, however this can be configured per-namespace by overriding the `log` method: - -Example [_stdout.js_](./examples/node/stdout.js): - -```js -var debug = require('debug'); -var error = debug('app:error'); - -// by default stderr is used -error('goes to stderr!'); - -var log = debug('app:log'); -// set this namespace to log via console.log -log.log = console.log.bind(console); // don't forget to bind to console! -log('goes to stdout'); -error('still goes to stderr!'); - -// set all output to go via console.info -// overrides all per-namespace log settings -debug.log = console.info.bind(console); -error('now goes to stdout via console.info'); -log('still goes to stdout, but via console.info now'); -``` - -## Checking whether a debug target is enabled - -After you've created a debug instance, you can determine whether or not it is -enabled by checking the `enabled` property: - -```javascript -const debug = require('debug')('http'); - -if (debug.enabled) { - // do stuff... -} -``` - -You can also manually toggle this property to force the debug instance to be -enabled or disabled. - - -## Authors - - - TJ Holowaychuk - - Nathan Rajlich - - Andrew Rhyne - -## Backers - -Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/debug#backer)] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -## Sponsors - -Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/debug#sponsor)] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -## License - -(The MIT License) - -Copyright (c) 2014-2017 TJ Holowaychuk <tj@vision-media.ca> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/mquery/node_modules/debug/karma.conf.js b/node_modules/mquery/node_modules/debug/karma.conf.js deleted file mode 100644 index 103a82d..0000000 --- a/node_modules/mquery/node_modules/debug/karma.conf.js +++ /dev/null @@ -1,70 +0,0 @@ -// Karma configuration -// Generated on Fri Dec 16 2016 13:09:51 GMT+0000 (UTC) - -module.exports = function(config) { - config.set({ - - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: '', - - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ['mocha', 'chai', 'sinon'], - - - // list of files / patterns to load in the browser - files: [ - 'dist/debug.js', - 'test/*spec.js' - ], - - - // list of files to exclude - exclude: [ - 'src/node.js' - ], - - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: { - }, - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ['progress'], - - - // web server port - port: 9876, - - - // enable / disable colors in the output (reporters and logs) - colors: true, - - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: true, - - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - browsers: ['PhantomJS'], - - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: false, - - // Concurrency level - // how many browser should be started simultaneous - concurrency: Infinity - }) -} diff --git a/node_modules/mquery/node_modules/debug/node.js b/node_modules/mquery/node_modules/debug/node.js deleted file mode 100644 index 7fc36fe..0000000 --- a/node_modules/mquery/node_modules/debug/node.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./src/node'); diff --git a/node_modules/mquery/node_modules/debug/package.json b/node_modules/mquery/node_modules/debug/package.json deleted file mode 100644 index fe85c2e..0000000 --- a/node_modules/mquery/node_modules/debug/package.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "_from": "debug@3.1.0", - "_id": "debug@3.1.0", - "_inBundle": false, - "_integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "_location": "/mquery/debug", - "_phantomChildren": {}, - "_requested": { - "type": "version", - "registry": true, - "raw": "debug@3.1.0", - "name": "debug", - "escapedName": "debug", - "rawSpec": "3.1.0", - "saveSpec": null, - "fetchSpec": "3.1.0" - }, - "_requiredBy": [ - "/mquery" - ], - "_resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "_shasum": "5bb5a0672628b64149566ba16819e61518c67261", - "_spec": "debug@3.1.0", - "_where": "/home/pruss/Dev/3-minute-website/node_modules/mquery", - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca" - }, - "browser": "./src/browser.js", - "bugs": { - "url": "https://github.com/visionmedia/debug/issues" - }, - "bundleDependencies": false, - "contributors": [ - { - "name": "Nathan Rajlich", - "email": "nathan@tootallnate.net", - "url": "http://n8.io" - }, - { - "name": "Andrew Rhyne", - "email": "rhyneandrew@gmail.com" - } - ], - "dependencies": { - "ms": "2.0.0" - }, - "deprecated": false, - "description": "small debugging utility", - "devDependencies": { - "browserify": "14.4.0", - "chai": "^3.5.0", - "concurrently": "^3.1.0", - "coveralls": "^2.11.15", - "eslint": "^3.12.1", - "istanbul": "^0.4.5", - "karma": "^1.3.0", - "karma-chai": "^0.1.0", - "karma-mocha": "^1.3.0", - "karma-phantomjs-launcher": "^1.0.2", - "karma-sinon": "^1.0.5", - "mocha": "^3.2.0", - "mocha-lcov-reporter": "^1.2.0", - "rimraf": "^2.5.4", - "sinon": "^1.17.6", - "sinon-chai": "^2.8.0" - }, - "homepage": "https://github.com/visionmedia/debug#readme", - "keywords": [ - "debug", - "log", - "debugger" - ], - "license": "MIT", - "main": "./src/index.js", - "name": "debug", - "repository": { - "type": "git", - "url": "git://github.com/visionmedia/debug.git" - }, - "version": "3.1.0" -} diff --git a/node_modules/mquery/node_modules/debug/src/browser.js b/node_modules/mquery/node_modules/debug/src/browser.js deleted file mode 100644 index f5149ff..0000000 --- a/node_modules/mquery/node_modules/debug/src/browser.js +++ /dev/null @@ -1,195 +0,0 @@ -/** - * This is the web browser implementation of `debug()`. - * - * Expose `debug()` as the module. - */ - -exports = module.exports = require('./debug'); -exports.log = log; -exports.formatArgs = formatArgs; -exports.save = save; -exports.load = load; -exports.useColors = useColors; -exports.storage = 'undefined' != typeof chrome - && 'undefined' != typeof chrome.storage - ? chrome.storage.local - : localstorage(); - -/** - * Colors. - */ - -exports.colors = [ - '#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', - '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', - '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', - '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', - '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', - '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', - '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', - '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', - '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', - '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', - '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33' -]; - -/** - * Currently only WebKit-based Web Inspectors, Firefox >= v31, - * and the Firebug extension (any Firefox version) are known - * to support "%c" CSS customizations. - * - * TODO: add a `localStorage` variable to explicitly enable/disable colors - */ - -function useColors() { - // NB: In an Electron preload script, document will be defined but not fully - // initialized. Since we know we're in Chrome, we'll just detect this case - // explicitly - if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') { - return true; - } - - // Internet Explorer and Edge do not support colors. - if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { - return false; - } - - // is webkit? http://stackoverflow.com/a/16459606/376773 - // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 - return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) || - // is firebug? http://stackoverflow.com/a/398120/376773 - (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) || - // is firefox >= v31? - // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages - (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) || - // double check webkit in userAgent just in case we are in a worker - (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); -} - -/** - * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. - */ - -exports.formatters.j = function(v) { - try { - return JSON.stringify(v); - } catch (err) { - return '[UnexpectedJSONParseError]: ' + err.message; - } -}; - - -/** - * Colorize log arguments if enabled. - * - * @api public - */ - -function formatArgs(args) { - var useColors = this.useColors; - - args[0] = (useColors ? '%c' : '') - + this.namespace - + (useColors ? ' %c' : ' ') - + args[0] - + (useColors ? '%c ' : ' ') - + '+' + exports.humanize(this.diff); - - if (!useColors) return; - - var c = 'color: ' + this.color; - args.splice(1, 0, c, 'color: inherit') - - // the final "%c" is somewhat tricky, because there could be other - // arguments passed either before or after the %c, so we need to - // figure out the correct index to insert the CSS into - var index = 0; - var lastC = 0; - args[0].replace(/%[a-zA-Z%]/g, function(match) { - if ('%%' === match) return; - index++; - if ('%c' === match) { - // we only are interested in the *last* %c - // (the user may have provided their own) - lastC = index; - } - }); - - args.splice(lastC, 0, c); -} - -/** - * Invokes `console.log()` when available. - * No-op when `console.log` is not a "function". - * - * @api public - */ - -function log() { - // this hackery is required for IE8/9, where - // the `console.log` function doesn't have 'apply' - return 'object' === typeof console - && console.log - && Function.prototype.apply.call(console.log, console, arguments); -} - -/** - * Save `namespaces`. - * - * @param {String} namespaces - * @api private - */ - -function save(namespaces) { - try { - if (null == namespaces) { - exports.storage.removeItem('debug'); - } else { - exports.storage.debug = namespaces; - } - } catch(e) {} -} - -/** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ - -function load() { - var r; - try { - r = exports.storage.debug; - } catch(e) {} - - // If debug isn't set in LS, and we're in Electron, try to load $DEBUG - if (!r && typeof process !== 'undefined' && 'env' in process) { - r = process.env.DEBUG; - } - - return r; -} - -/** - * Enable namespaces listed in `localStorage.debug` initially. - */ - -exports.enable(load()); - -/** - * Localstorage attempts to return the localstorage. - * - * This is necessary because safari throws - * when a user disables cookies/localstorage - * and you attempt to access it. - * - * @return {LocalStorage} - * @api private - */ - -function localstorage() { - try { - return window.localStorage; - } catch (e) {} -} diff --git a/node_modules/mquery/node_modules/debug/src/debug.js b/node_modules/mquery/node_modules/debug/src/debug.js deleted file mode 100644 index 77e6384..0000000 --- a/node_modules/mquery/node_modules/debug/src/debug.js +++ /dev/null @@ -1,225 +0,0 @@ - -/** - * This is the common logic for both the Node.js and web browser - * implementations of `debug()`. - * - * Expose `debug()` as the module. - */ - -exports = module.exports = createDebug.debug = createDebug['default'] = createDebug; -exports.coerce = coerce; -exports.disable = disable; -exports.enable = enable; -exports.enabled = enabled; -exports.humanize = require('ms'); - -/** - * Active `debug` instances. - */ -exports.instances = []; - -/** - * The currently active debug mode names, and names to skip. - */ - -exports.names = []; -exports.skips = []; - -/** - * Map of special "%n" handling functions, for the debug "format" argument. - * - * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". - */ - -exports.formatters = {}; - -/** - * Select a color. - * @param {String} namespace - * @return {Number} - * @api private - */ - -function selectColor(namespace) { - var hash = 0, i; - - for (i in namespace) { - hash = ((hash << 5) - hash) + namespace.charCodeAt(i); - hash |= 0; // Convert to 32bit integer - } - - return exports.colors[Math.abs(hash) % exports.colors.length]; -} - -/** - * Create a debugger with the given `namespace`. - * - * @param {String} namespace - * @return {Function} - * @api public - */ - -function createDebug(namespace) { - - var prevTime; - - function debug() { - // disabled? - if (!debug.enabled) return; - - var self = debug; - - // set `diff` timestamp - var curr = +new Date(); - var ms = curr - (prevTime || curr); - self.diff = ms; - self.prev = prevTime; - self.curr = curr; - prevTime = curr; - - // turn the `arguments` into a proper Array - var args = new Array(arguments.length); - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i]; - } - - args[0] = exports.coerce(args[0]); - - if ('string' !== typeof args[0]) { - // anything else let's inspect with %O - args.unshift('%O'); - } - - // apply any `formatters` transformations - var index = 0; - args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) { - // if we encounter an escaped % then don't increase the array index - if (match === '%%') return match; - index++; - var formatter = exports.formatters[format]; - if ('function' === typeof formatter) { - var val = args[index]; - match = formatter.call(self, val); - - // now we need to remove `args[index]` since it's inlined in the `format` - args.splice(index, 1); - index--; - } - return match; - }); - - // apply env-specific formatting (colors, etc.) - exports.formatArgs.call(self, args); - - var logFn = debug.log || exports.log || console.log.bind(console); - logFn.apply(self, args); - } - - debug.namespace = namespace; - debug.enabled = exports.enabled(namespace); - debug.useColors = exports.useColors(); - debug.color = selectColor(namespace); - debug.destroy = destroy; - - // env-specific initialization logic for debug instances - if ('function' === typeof exports.init) { - exports.init(debug); - } - - exports.instances.push(debug); - - return debug; -} - -function destroy () { - var index = exports.instances.indexOf(this); - if (index !== -1) { - exports.instances.splice(index, 1); - return true; - } else { - return false; - } -} - -/** - * Enables a debug mode by namespaces. This can include modes - * separated by a colon and wildcards. - * - * @param {String} namespaces - * @api public - */ - -function enable(namespaces) { - exports.save(namespaces); - - exports.names = []; - exports.skips = []; - - var i; - var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); - var len = split.length; - - for (i = 0; i < len; i++) { - if (!split[i]) continue; // ignore empty strings - namespaces = split[i].replace(/\*/g, '.*?'); - if (namespaces[0] === '-') { - exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); - } else { - exports.names.push(new RegExp('^' + namespaces + '$')); - } - } - - for (i = 0; i < exports.instances.length; i++) { - var instance = exports.instances[i]; - instance.enabled = exports.enabled(instance.namespace); - } -} - -/** - * Disable debug output. - * - * @api public - */ - -function disable() { - exports.enable(''); -} - -/** - * Returns true if the given mode name is enabled, false otherwise. - * - * @param {String} name - * @return {Boolean} - * @api public - */ - -function enabled(name) { - if (name[name.length - 1] === '*') { - return true; - } - var i, len; - for (i = 0, len = exports.skips.length; i < len; i++) { - if (exports.skips[i].test(name)) { - return false; - } - } - for (i = 0, len = exports.names.length; i < len; i++) { - if (exports.names[i].test(name)) { - return true; - } - } - return false; -} - -/** - * Coerce `val`. - * - * @param {Mixed} val - * @return {Mixed} - * @api private - */ - -function coerce(val) { - if (val instanceof Error) return val.stack || val.message; - return val; -} diff --git a/node_modules/mquery/node_modules/debug/src/index.js b/node_modules/mquery/node_modules/debug/src/index.js deleted file mode 100644 index cabcbcd..0000000 --- a/node_modules/mquery/node_modules/debug/src/index.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Detect Electron renderer process, which is node, but we should - * treat as a browser. - */ - -if (typeof process === 'undefined' || process.type === 'renderer') { - module.exports = require('./browser.js'); -} else { - module.exports = require('./node.js'); -} diff --git a/node_modules/mquery/node_modules/debug/src/node.js b/node_modules/mquery/node_modules/debug/src/node.js deleted file mode 100644 index d666fb9..0000000 --- a/node_modules/mquery/node_modules/debug/src/node.js +++ /dev/null @@ -1,186 +0,0 @@ -/** - * Module dependencies. - */ - -var tty = require('tty'); -var util = require('util'); - -/** - * This is the Node.js implementation of `debug()`. - * - * Expose `debug()` as the module. - */ - -exports = module.exports = require('./debug'); -exports.init = init; -exports.log = log; -exports.formatArgs = formatArgs; -exports.save = save; -exports.load = load; -exports.useColors = useColors; - -/** - * Colors. - */ - -exports.colors = [ 6, 2, 3, 4, 5, 1 ]; - -try { - var supportsColor = require('supports-color'); - if (supportsColor && supportsColor.level >= 2) { - exports.colors = [ - 20, 21, 26, 27, 32, 33, 38, 39, 40, 41, 42, 43, 44, 45, 56, 57, 62, 63, 68, - 69, 74, 75, 76, 77, 78, 79, 80, 81, 92, 93, 98, 99, 112, 113, 128, 129, 134, - 135, 148, 149, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 173, 178, 179, 184, 185, 196, 197, 198, 199, 200, 201, 202, 203, 204, - 205, 206, 207, 208, 209, 214, 215, 220, 221 - ]; - } -} catch (err) { - // swallow - we only care if `supports-color` is available; it doesn't have to be. -} - -/** - * Build up the default `inspectOpts` object from the environment variables. - * - * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js - */ - -exports.inspectOpts = Object.keys(process.env).filter(function (key) { - return /^debug_/i.test(key); -}).reduce(function (obj, key) { - // camel-case - var prop = key - .substring(6) - .toLowerCase() - .replace(/_([a-z])/g, function (_, k) { return k.toUpperCase() }); - - // coerce string value into JS value - var val = process.env[key]; - if (/^(yes|on|true|enabled)$/i.test(val)) val = true; - else if (/^(no|off|false|disabled)$/i.test(val)) val = false; - else if (val === 'null') val = null; - else val = Number(val); - - obj[prop] = val; - return obj; -}, {}); - -/** - * Is stdout a TTY? Colored output is enabled when `true`. - */ - -function useColors() { - return 'colors' in exports.inspectOpts - ? Boolean(exports.inspectOpts.colors) - : tty.isatty(process.stderr.fd); -} - -/** - * Map %o to `util.inspect()`, all on a single line. - */ - -exports.formatters.o = function(v) { - this.inspectOpts.colors = this.useColors; - return util.inspect(v, this.inspectOpts) - .split('\n').map(function(str) { - return str.trim() - }).join(' '); -}; - -/** - * Map %o to `util.inspect()`, allowing multiple lines if needed. - */ - -exports.formatters.O = function(v) { - this.inspectOpts.colors = this.useColors; - return util.inspect(v, this.inspectOpts); -}; - -/** - * Adds ANSI color escape codes if enabled. - * - * @api public - */ - -function formatArgs(args) { - var name = this.namespace; - var useColors = this.useColors; - - if (useColors) { - var c = this.color; - var colorCode = '\u001b[3' + (c < 8 ? c : '8;5;' + c); - var prefix = ' ' + colorCode + ';1m' + name + ' ' + '\u001b[0m'; - - args[0] = prefix + args[0].split('\n').join('\n' + prefix); - args.push(colorCode + 'm+' + exports.humanize(this.diff) + '\u001b[0m'); - } else { - args[0] = getDate() + name + ' ' + args[0]; - } -} - -function getDate() { - if (exports.inspectOpts.hideDate) { - return ''; - } else { - return new Date().toISOString() + ' '; - } -} - -/** - * Invokes `util.format()` with the specified arguments and writes to stderr. - */ - -function log() { - return process.stderr.write(util.format.apply(util, arguments) + '\n'); -} - -/** - * Save `namespaces`. - * - * @param {String} namespaces - * @api private - */ - -function save(namespaces) { - if (null == namespaces) { - // If you set a process.env field to null or undefined, it gets cast to the - // string 'null' or 'undefined'. Just delete instead. - delete process.env.DEBUG; - } else { - process.env.DEBUG = namespaces; - } -} - -/** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ - -function load() { - return process.env.DEBUG; -} - -/** - * Init logic for `debug` instances. - * - * Create a new `inspectOpts` object in case `useColors` is set - * differently for a particular `debug` instance. - */ - -function init (debug) { - debug.inspectOpts = {}; - - var keys = Object.keys(exports.inspectOpts); - for (var i = 0; i < keys.length; i++) { - debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; - } -} - -/** - * Enable namespaces listed in `process.env.DEBUG` initially. - */ - -exports.enable(load()); diff --git a/node_modules/mquery/package.json b/node_modules/mquery/package.json deleted file mode 100644 index 3e679dc..0000000 --- a/node_modules/mquery/package.json +++ /dev/null @@ -1,114 +0,0 @@ -{ - "_from": "mquery@3.2.2", - "_id": "mquery@3.2.2", - "_inBundle": false, - "_integrity": "sha512-XB52992COp0KP230I3qloVUbkLUxJIu328HBP2t2EsxSFtf4W1HPSOBWOXf1bqxK4Xbb66lfMJ+Bpfd9/yZE1Q==", - "_location": "/mquery", - "_phantomChildren": { - "ms": "2.0.0" - }, - "_requested": { - "type": "version", - "registry": true, - "raw": "mquery@3.2.2", - "name": "mquery", - "escapedName": "mquery", - "rawSpec": "3.2.2", - "saveSpec": null, - "fetchSpec": "3.2.2" - }, - "_requiredBy": [ - "/mongoose" - ], - "_resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.2.tgz", - "_shasum": "e1383a3951852ce23e37f619a9b350f1fb3664e7", - "_spec": "mquery@3.2.2", - "_where": "/home/pruss/Dev/3-minute-website/node_modules/mongoose", - "author": { - "name": "Aaron Heckmann", - "email": "aaron.heckmann+github@gmail.com" - }, - "bugs": { - "url": "https://github.com/aheckmann/mquery/issues/new" - }, - "bundleDependencies": false, - "dependencies": { - "bluebird": "3.5.1", - "debug": "3.1.0", - "regexp-clone": "^1.0.0", - "safe-buffer": "5.1.2", - "sliced": "1.0.1" - }, - "deprecated": false, - "description": "Expressive query building for MongoDB", - "devDependencies": { - "eslint": "5.x", - "mocha": "4.1.0", - "mongodb": "3.1.1" - }, - "engines": { - "node": ">=4.0.0" - }, - "eslintConfig": { - "env": { - "node": true, - "mocha": true, - "es6": false - }, - "extends": "eslint:recommended", - "parserOptions": { - "ecmaVersion": 5 - }, - "rules": { - "comma-style": "error", - "consistent-this": [ - "error", - "_this" - ], - "indent": [ - "error", - 2, - { - "SwitchCase": 1, - "VariableDeclarator": 2 - } - ], - "keyword-spacing": "error", - "no-console": "off", - "no-multi-spaces": "error", - "func-call-spacing": "error", - "no-trailing-spaces": "error", - "quotes": [ - "error", - "single" - ], - "semi": "error", - "space-before-blocks": "error", - "space-before-function-paren": [ - "error", - "never" - ], - "space-infix-ops": "error", - "space-unary-ops": "error" - } - }, - "homepage": "https://github.com/aheckmann/mquery/", - "keywords": [ - "mongodb", - "query", - "builder" - ], - "license": "MIT", - "main": "lib/mquery.js", - "name": "mquery", - "repository": { - "type": "git", - "url": "git://github.com/aheckmann/mquery.git" - }, - "scripts": { - "fix-lint": "eslint . --fix", - "lint": "eslint .", - "test": "mocha test/index.js test/*.test.js" - }, - "version": "3.2.2" -} diff --git a/node_modules/mquery/test/collection/browser.js b/node_modules/mquery/test/collection/browser.js deleted file mode 100644 index e69de29..0000000 diff --git a/node_modules/mquery/test/collection/mongo.js b/node_modules/mquery/test/collection/mongo.js deleted file mode 100644 index e69de29..0000000 diff --git a/node_modules/mquery/test/collection/node.js b/node_modules/mquery/test/collection/node.js deleted file mode 100644 index 8ac380b..0000000 --- a/node_modules/mquery/test/collection/node.js +++ /dev/null @@ -1,28 +0,0 @@ - -var assert = require('assert'); -var mongo = require('mongodb'); - -var uri = process.env.MQUERY_URI || 'mongodb://localhost/mquery'; -var client; -var db; - -exports.getCollection = function(cb) { - mongo.MongoClient.connect(uri, function(err, _client) { - assert.ifError(err); - client = _client; - db = client.db(); - - var collection = db.collection('stuff'); - - // clean test db before starting - db.dropDatabase(function() { - cb(null, collection); - }); - }); -}; - -exports.dropCollection = function(cb) { - db.dropDatabase(function() { - client.close(cb); - }); -}; diff --git a/node_modules/mquery/test/env.js b/node_modules/mquery/test/env.js deleted file mode 100644 index 38385b0..0000000 --- a/node_modules/mquery/test/env.js +++ /dev/null @@ -1,21 +0,0 @@ - -var env = require('../').env; - -console.log('environment: %s', env.type); - -var col; -switch (env.type) { - case 'node': - col = require('./collection/node'); - break; - case 'mongo': - col = require('./collection/mongo'); - break; - case 'browser': - col = require('./collection/browser'); - break; - default: - throw new Error('missing collection implementation for environment: ' + env.type); -} - -module.exports = exports = col; diff --git a/node_modules/mquery/test/index.js b/node_modules/mquery/test/index.js deleted file mode 100644 index 44adb17..0000000 --- a/node_modules/mquery/test/index.js +++ /dev/null @@ -1,3076 +0,0 @@ -var mquery = require('../'); -var assert = require('assert'); - -/* global Map */ - -describe('mquery', function() { - var col; - - before(function(done) { - // get the env specific collection interface - require('./env').getCollection(function(err, collection) { - assert.ifError(err); - col = collection; - done(); - }); - }); - - after(function(done) { - require('./env').dropCollection(done); - }); - - describe('mquery', function() { - it('is a function', function() { - assert.equal('function', typeof mquery); - }); - it('creates instances with the `new` keyword', function() { - assert.ok(mquery() instanceof mquery); - }); - describe('defaults', function() { - it('are set', function() { - var m = mquery(); - assert.strictEqual(undefined, m.op); - assert.deepEqual({}, m.options); - }); - }); - describe('criteria', function() { - it('if collection-like is used as collection', function() { - var m = mquery(col); - assert.equal(col, m._collection.collection); - }); - it('non-collection-like is used as criteria', function() { - var m = mquery({ works: true }); - assert.ok(!m._collection); - assert.deepEqual({ works: true }, m._conditions); - }); - }); - describe('options', function() { - it('are merged when passed', function() { - var m; - m = mquery(col, { safe: true }); - assert.deepEqual({ safe: true }, m.options); - m = mquery({ name: 'mquery' }, { safe: true }); - assert.deepEqual({ safe: true }, m.options); - }); - }); - }); - - describe('toConstructor', function() { - it('creates subclasses of mquery', function() { - var opts = { safe: { w: 'majority' }, readPreference: 'p' }; - var match = { name: 'test', count: { $gt: 101 }}; - var select = { name: 1, count: 0 }; - var update = { $set: { x: true }}; - var path = 'street'; - - var q = mquery().setOptions(opts); - q.where(match); - q.select(select); - q.update(update); - q.where(path); - q.find(); - - var M = q.toConstructor(); - var m = M(); - - assert.ok(m instanceof mquery); - assert.deepEqual(opts, m.options); - assert.deepEqual(match, m._conditions); - assert.deepEqual(select, m._fields); - assert.deepEqual(update, m._update); - assert.equal(path, m._path); - assert.equal('find', m.op); - }); - }); - - describe('setOptions', function() { - it('calls associated methods', function() { - var m = mquery(); - assert.equal(m._collection, null); - m.setOptions({ collection: col }); - assert.equal(m._collection.collection, col); - }); - it('directly sets option when no method exists', function() { - var m = mquery(); - assert.equal(m.options.woot, null); - m.setOptions({ woot: 'yay' }); - assert.equal(m.options.woot, 'yay'); - }); - it('is chainable', function() { - var m = mquery(), - n; - - n = m.setOptions(); - assert.equal(m, n); - n = m.setOptions({ x: 1 }); - assert.equal(m, n); - }); - }); - - describe('collection', function() { - it('sets the _collection', function() { - var m = mquery(); - m.collection(col); - assert.equal(m._collection.collection, col); - }); - it('is chainable', function() { - var m = mquery(); - var n = m.collection(col); - assert.equal(m, n); - }); - }); - - describe('$where', function() { - it('sets the $where condition', function() { - var m = mquery(); - function go() {} - m.$where(go); - assert.ok(go === m._conditions.$where); - }); - it('is chainable', function() { - var m = mquery(); - var n = m.$where('x'); - assert.equal(m, n); - }); - }); - - describe('where', function() { - it('without arguments', function() { - var m = mquery(); - m.where(); - assert.deepEqual({}, m._conditions); - }); - it('with non-string/object argument', function() { - var m = mquery(); - - assert.throws(function() { - m.where([]); - }, /path must be a string or object/); - }); - describe('with one argument', function() { - it('that is an object', function() { - var m = mquery(); - m.where({ name: 'flawed' }); - assert.strictEqual(m._conditions.name, 'flawed'); - }); - it('that is a query', function() { - var m = mquery({ name: 'first' }); - var n = mquery({ name: 'changed' }); - m.where(n); - assert.strictEqual(m._conditions.name, 'changed'); - }); - it('that is a string', function() { - var m = mquery(); - m.where('name'); - assert.equal('name', m._path); - assert.strictEqual(m._conditions.name, undefined); - }); - }); - it('with two arguments', function() { - var m = mquery(); - m.where('name', 'The Great Pumpkin'); - assert.equal('name', m._path); - assert.strictEqual(m._conditions.name, 'The Great Pumpkin'); - }); - it('is chainable', function() { - var m = mquery(), - n; - - n = m.where('x', 'y'); - assert.equal(m, n); - n = m.where(); - assert.equal(m, n); - }); - }); - describe('equals', function() { - it('must be called after where()', function() { - var m = mquery(); - assert.throws(function() { - m.equals(); - }, /must be used after where/); - }); - it('sets value of path set with where()', function() { - var m = mquery(); - m.where('age').equals(1000); - assert.deepEqual({ age: 1000 }, m._conditions); - }); - it('is chainable', function() { - var m = mquery(); - var n = m.where('x').equals(3); - assert.equal(m, n); - }); - }); - describe('eq', function() { - it('is alias of equals', function() { - var m = mquery(); - m.where('age').eq(1000); - assert.deepEqual({ age: 1000 }, m._conditions); - }); - }); - describe('or', function() { - it('pushes onto the internal $or condition', function() { - var m = mquery(); - m.or({ 'Nightmare Before Christmas': true }); - assert.deepEqual([{'Nightmare Before Christmas': true }], m._conditions.$or); - }); - it('allows passing arrays', function() { - var m = mquery(); - var arg = [{ 'Nightmare Before Christmas': true }, { x: 1 }]; - m.or(arg); - assert.deepEqual(arg, m._conditions.$or); - }); - it('allows calling multiple times', function() { - var m = mquery(); - var arg = [{ looper: true }, { x: 1 }]; - m.or(arg); - m.or({ y: 1 }); - m.or([{ w: 'oo' }, { z: 'oo'} ]); - assert.deepEqual([{looper:true},{x:1},{y:1},{w:'oo'},{z:'oo'}], m._conditions.$or); - }); - it('is chainable', function() { - var m = mquery(); - m.or({ o: 'k'}).where('name', 'table'); - assert.deepEqual({ name: 'table', $or: [{ o: 'k' }] }, m._conditions); - }); - }); - - describe('nor', function() { - it('pushes onto the internal $nor condition', function() { - var m = mquery(); - m.nor({ 'Nightmare Before Christmas': true }); - assert.deepEqual([{'Nightmare Before Christmas': true }], m._conditions.$nor); - }); - it('allows passing arrays', function() { - var m = mquery(); - var arg = [{ 'Nightmare Before Christmas': true }, { x: 1 }]; - m.nor(arg); - assert.deepEqual(arg, m._conditions.$nor); - }); - it('allows calling multiple times', function() { - var m = mquery(); - var arg = [{ looper: true }, { x: 1 }]; - m.nor(arg); - m.nor({ y: 1 }); - m.nor([{ w: 'oo' }, { z: 'oo'} ]); - assert.deepEqual([{looper:true},{x:1},{y:1},{w:'oo'},{z:'oo'}], m._conditions.$nor); - }); - it('is chainable', function() { - var m = mquery(); - m.nor({ o: 'k'}).where('name', 'table'); - assert.deepEqual({ name: 'table', $nor: [{ o: 'k' }] }, m._conditions); - }); - }); - - describe('and', function() { - it('pushes onto the internal $and condition', function() { - var m = mquery(); - m.and({ 'Nightmare Before Christmas': true }); - assert.deepEqual([{'Nightmare Before Christmas': true }], m._conditions.$and); - }); - it('allows passing arrays', function() { - var m = mquery(); - var arg = [{ 'Nightmare Before Christmas': true }, { x: 1 }]; - m.and(arg); - assert.deepEqual(arg, m._conditions.$and); - }); - it('allows calling multiple times', function() { - var m = mquery(); - var arg = [{ looper: true }, { x: 1 }]; - m.and(arg); - m.and({ y: 1 }); - m.and([{ w: 'oo' }, { z: 'oo'} ]); - assert.deepEqual([{looper:true},{x:1},{y:1},{w:'oo'},{z:'oo'}], m._conditions.$and); - }); - it('is chainable', function() { - var m = mquery(); - m.and({ o: 'k'}).where('name', 'table'); - assert.deepEqual({ name: 'table', $and: [{ o: 'k' }] }, m._conditions); - }); - }); - - function generalCondition(type) { - return function() { - it('accepts 2 args', function() { - var m = mquery()[type]('count', 3); - var check = {}; - check['$' + type] = 3; - assert.deepEqual(m._conditions.count, check); - }); - it('uses previously set `where` path if 1 arg passed', function() { - var m = mquery().where('count')[type](3); - var check = {}; - check['$' + type] = 3; - assert.deepEqual(m._conditions.count, check); - }); - it('throws if 1 arg was passed but no previous `where` was used', function() { - assert.throws(function() { - mquery()[type](3); - }, /must be used after where/); - }); - it('is chainable', function() { - var m = mquery().where('count')[type](3).where('x', 8); - var check = {x: 8, count: {}}; - check.count['$' + type] = 3; - assert.deepEqual(m._conditions, check); - }); - it('overwrites previous value', function() { - var m = mquery().where('count')[type](3)[type](8); - var check = {}; - check['$' + type] = 8; - assert.deepEqual(m._conditions.count, check); - }); - }; - } - - 'gt gte lt lte ne in nin regex size maxDistance minDistance'.split(' ').forEach(function(type) { - describe(type, generalCondition(type)); - }); - - describe('mod', function() { - describe('with 1 argument', function() { - it('requires a previous where()', function() { - assert.throws(function() { - mquery().mod([30, 10]); - }, /must be used after where/); - }); - it('works', function() { - var m = mquery().where('madmen').mod([10,20]); - assert.deepEqual(m._conditions, { madmen: { $mod: [10,20] }}); - }); - }); - - describe('with 2 arguments and second is non-Array', function() { - it('requires a previous where()', function() { - assert.throws(function() { - mquery().mod('x', 10); - }, /must be used after where/); - }); - it('works', function() { - var m = mquery().where('madmen').mod(10, 20); - assert.deepEqual(m._conditions, { madmen: { $mod: [10,20] }}); - }); - }); - - it('with 2 arguments and second is an array', function() { - var m = mquery().mod('madmen', [10,20]); - assert.deepEqual(m._conditions, { madmen: { $mod: [10,20] }}); - }); - - it('with 3 arguments', function() { - var m = mquery().mod('madmen', 10, 20); - assert.deepEqual(m._conditions, { madmen: { $mod: [10,20] }}); - }); - - it('is chainable', function() { - var m = mquery().mod('madmen', 10, 20).where('x', 8); - var check = { madmen: { $mod: [10,20] }, x: 8}; - assert.deepEqual(m._conditions, check); - }); - }); - - describe('exists', function() { - it('with 0 args', function() { - it('throws if not used after where()', function() { - assert.throws(function() { - mquery().exists(); - }, /must be used after where/); - }); - it('works', function() { - var m = mquery().where('name').exists(); - var check = { name: { $exists: true }}; - assert.deepEqual(m._conditions, check); - }); - }); - - describe('with 1 arg', function() { - describe('that is boolean', function() { - it('throws if not used after where()', function() { - assert.throws(function() { - mquery().exists(); - }, /must be used after where/); - }); - it('works', function() { - var m = mquery().exists('name', false); - var check = { name: { $exists: false }}; - assert.deepEqual(m._conditions, check); - }); - }); - describe('that is not boolean', function() { - it('sets the value to `true`', function() { - var m = mquery().where('name').exists('yummy'); - var check = { yummy: { $exists: true }}; - assert.deepEqual(m._conditions, check); - }); - }); - }); - - describe('with 2 args', function() { - it('works', function() { - var m = mquery().exists('yummy', false); - var check = { yummy: { $exists: false }}; - assert.deepEqual(m._conditions, check); - }); - }); - - it('is chainable', function() { - var m = mquery().where('name').exists().find({ x: 1 }); - var check = { name: { $exists: true }, x: 1}; - assert.deepEqual(m._conditions, check); - }); - }); - - describe('elemMatch', function() { - describe('with null/undefined first argument', function() { - assert.throws(function() { - mquery().elemMatch(); - }, /Invalid argument/); - assert.throws(function() { - mquery().elemMatch(null); - }, /Invalid argument/); - assert.doesNotThrow(function() { - mquery().elemMatch('', {}); - }); - }); - - describe('with 1 argument', function() { - it('throws if not a function or object', function() { - assert.throws(function() { - mquery().elemMatch([]); - }, /Invalid argument/); - }); - - describe('that is an object', function() { - it('throws if no previous `where` was used', function() { - assert.throws(function() { - mquery().elemMatch({}); - }, /must be used after where/); - }); - it('works', function() { - var m = mquery().where('comment').elemMatch({ author: 'joe', votes: {$gte: 3 }}); - assert.deepEqual({ comment: { $elemMatch: { author: 'joe', votes: {$gte: 3}}}}, m._conditions); - }); - }); - describe('that is a function', function() { - it('throws if no previous `where` was used', function() { - assert.throws(function() { - mquery().elemMatch(function() {}); - }, /must be used after where/); - }); - it('works', function() { - var m = mquery().where('comment').elemMatch(function(query) { - query.where({ author: 'joe', votes: {$gte: 3 }}); - }); - assert.deepEqual({ comment: { $elemMatch: { author: 'joe', votes: {$gte: 3}}}}, m._conditions); - }); - }); - }); - - describe('with 2 arguments', function() { - describe('and the 2nd is an object', function() { - it('works', function() { - var m = mquery().elemMatch('comment', { author: 'joe', votes: {$gte: 3 }}); - assert.deepEqual({ comment: { $elemMatch: { author: 'joe', votes: {$gte: 3}}}}, m._conditions); - }); - }); - describe('and the 2nd is a function', function() { - it('works', function() { - var m = mquery().elemMatch('comment', function(query) { - query.where({ author: 'joe', votes: {$gte: 3 }}); - }); - assert.deepEqual({ comment: { $elemMatch: { author: 'joe', votes: {$gte: 3}}}}, m._conditions); - }); - }); - it('and the 2nd is not a function or object', function() { - assert.throws(function() { - mquery().elemMatch('comment', []); - }, /Invalid argument/); - }); - }); - }); - - describe('within', function() { - it('is chainable', function() { - var m = mquery(); - assert.equal(m.where('a').within(), m); - }); - describe('when called with arguments', function() { - it('must follow where()', function() { - assert.throws(function() { - mquery().within([]); - }, /must be used after where/); - }); - - describe('of length 1', function() { - it('throws if not a recognized shape', function() { - assert.throws(function() { - mquery().where('loc').within({}); - }, /Invalid argument/); - assert.throws(function() { - mquery().where('loc').within(null); - }, /Invalid argument/); - }); - it('delegates to circle when center exists', function() { - var m = mquery().where('loc').within({ center: [10,10], radius: 3 }); - assert.deepEqual({ $geoWithin: {$center:[[10,10], 3]}}, m._conditions.loc); - }); - it('delegates to box when exists', function() { - var m = mquery().where('loc').within({ box: [[10,10], [11,14]] }); - assert.deepEqual({ $geoWithin: {$box:[[10,10], [11,14]]}}, m._conditions.loc); - }); - it('delegates to polygon when exists', function() { - var m = mquery().where('loc').within({ polygon: [[10,10], [11,14],[10,9]] }); - assert.deepEqual({ $geoWithin: {$polygon:[[10,10], [11,14],[10,9]]}}, m._conditions.loc); - }); - it('delegates to geometry when exists', function() { - var m = mquery().where('loc').within({ type: 'Polygon', coordinates: [[10,10], [11,14],[10,9]] }); - assert.deepEqual({ $geoWithin: {$geometry: {type:'Polygon', coordinates: [[10,10], [11,14],[10,9]]}}}, m._conditions.loc); - }); - }); - - describe('of length 2', function() { - it('delegates to box()', function() { - var m = mquery().where('loc').within([1,2],[2,5]); - assert.deepEqual(m._conditions.loc, { $geoWithin: { $box: [[1,2],[2,5]]}}); - }); - }); - - describe('of length > 2', function() { - it('delegates to polygon()', function() { - var m = mquery().where('loc').within([1,2],[2,5],[2,4],[1,3]); - assert.deepEqual(m._conditions.loc, { $geoWithin: { $polygon: [[1,2],[2,5],[2,4],[1,3]]}}); - }); - }); - }); - }); - - describe('geoWithin', function() { - before(function() { - mquery.use$geoWithin = false; - }); - after(function() { - mquery.use$geoWithin = true; - }); - describe('when called with arguments', function() { - describe('of length 1', function() { - it('delegates to circle when center exists', function() { - var m = mquery().where('loc').within({ center: [10,10], radius: 3 }); - assert.deepEqual({ $within: {$center:[[10,10], 3]}}, m._conditions.loc); - }); - it('delegates to box when exists', function() { - var m = mquery().where('loc').within({ box: [[10,10], [11,14]] }); - assert.deepEqual({ $within: {$box:[[10,10], [11,14]]}}, m._conditions.loc); - }); - it('delegates to polygon when exists', function() { - var m = mquery().where('loc').within({ polygon: [[10,10], [11,14],[10,9]] }); - assert.deepEqual({ $within: {$polygon:[[10,10], [11,14],[10,9]]}}, m._conditions.loc); - }); - it('delegates to geometry when exists', function() { - var m = mquery().where('loc').within({ type: 'Polygon', coordinates: [[10,10], [11,14],[10,9]] }); - assert.deepEqual({ $within: {$geometry: {type:'Polygon', coordinates: [[10,10], [11,14],[10,9]]}}}, m._conditions.loc); - }); - }); - - describe('of length 2', function() { - it('delegates to box()', function() { - var m = mquery().where('loc').within([1,2],[2,5]); - assert.deepEqual(m._conditions.loc, { $within: { $box: [[1,2],[2,5]]}}); - }); - }); - - describe('of length > 2', function() { - it('delegates to polygon()', function() { - var m = mquery().where('loc').within([1,2],[2,5],[2,4],[1,3]); - assert.deepEqual(m._conditions.loc, { $within: { $polygon: [[1,2],[2,5],[2,4],[1,3]]}}); - }); - }); - }); - }); - - describe('box', function() { - describe('with 1 argument', function() { - it('throws', function() { - assert.throws(function() { - mquery().box('sometihng'); - }, /Invalid argument/); - }); - }); - describe('with > 3 arguments', function() { - it('throws', function() { - assert.throws(function() { - mquery().box(1,2,3,4); - }, /Invalid argument/); - }); - }); - - describe('with 2 arguments', function() { - it('throws if not used after where()', function() { - assert.throws(function() { - mquery().box([],[]); - }, /must be used after where/); - }); - it('works', function() { - var m = mquery().where('loc').box([1,2],[3,4]); - assert.deepEqual(m._conditions.loc, { $geoWithin: { $box: [[1,2],[3,4]] }}); - }); - }); - - describe('with 3 arguments', function() { - it('works', function() { - var m = mquery().box('loc', [1,2],[3,4]); - assert.deepEqual(m._conditions.loc, { $geoWithin: { $box: [[1,2],[3,4]] }}); - }); - }); - }); - - describe('polygon', function() { - describe('when first argument is not a string', function() { - it('throws if not used after where()', function() { - assert.throws(function() { - mquery().polygon({}); - }, /must be used after where/); - - assert.doesNotThrow(function() { - mquery().where('loc').polygon([1,2], [2,3], [3,6]); - }); - }); - - it('assigns arguments to within polygon condition', function() { - var m = mquery().where('loc').polygon([1,2], [2,3], [3,6]); - assert.deepEqual(m._conditions, { loc: {$geoWithin: {$polygon: [[1,2],[2,3],[3,6]]}} }); - }); - }); - - describe('when first arg is a string', function() { - it('assigns remaining arguments to within polygon condition', function() { - var m = mquery().polygon('loc', [1,2], [2,3], [3,6]); - assert.deepEqual(m._conditions, { loc: {$geoWithin: {$polygon: [[1,2],[2,3],[3,6]]}} }); - }); - }); - }); - - describe('circle', function() { - describe('with one arg', function() { - it('must follow where()', function() { - assert.throws(function() { - mquery().circle('x'); - }, /must be used after where/); - assert.doesNotThrow(function() { - mquery().where('loc').circle({center:[0,0], radius: 3 }); - }); - }); - it('works', function() { - var m = mquery().where('loc').circle({center:[0,0], radius: 3 }); - assert.deepEqual(m._conditions, { loc: { $geoWithin: {$center: [[0,0],3] }}}); - }); - }); - describe('with 3 args', function() { - it('throws', function() { - assert.throws(function() { - mquery().where('loc').circle(1,2,3); - }, /Invalid argument/); - }); - }); - describe('requires radius and center', function() { - assert.throws(function() { - mquery().circle('loc', { center: 1 }); - }, /center and radius are required/); - assert.throws(function() { - mquery().circle('loc', { radius: 1 }); - }, /center and radius are required/); - assert.doesNotThrow(function() { - mquery().circle('loc', { center: [1,2], radius: 1 }); - }); - }); - }); - - describe('geometry', function() { - // within + intersects - var point = { type: 'Point', coordinates: [[0,0],[1,1]] }; - - it('must be called after within or intersects', function(done) { - assert.throws(function() { - mquery().where('a').geometry(point); - }, /must come after/); - - assert.doesNotThrow(function() { - mquery().where('a').within().geometry(point); - }); - - assert.doesNotThrow(function() { - mquery().where('a').intersects().geometry(point); - }); - - done(); - }); - - describe('when called with one argument', function() { - describe('after within()', function() { - it('and arg quacks like geoJSON', function(done) { - var m = mquery().where('a').within().geometry(point); - assert.deepEqual({ a: { $geoWithin: { $geometry: point }}}, m._conditions); - done(); - }); - }); - - describe('after intersects()', function() { - it('and arg quacks like geoJSON', function(done) { - var m = mquery().where('a').intersects().geometry(point); - assert.deepEqual({ a: { $geoIntersects: { $geometry: point }}}, m._conditions); - done(); - }); - }); - - it('and arg does not quack like geoJSON', function(done) { - assert.throws(function() { - mquery().where('b').within().geometry({type:1, coordinates:2}); - }, /Invalid argument/); - done(); - }); - }); - - describe('when called with zero arguments', function() { - it('throws', function(done) { - assert.throws(function() { - mquery().where('a').within().geometry(); - }, /Invalid argument/); - - done(); - }); - }); - - describe('when called with more than one arguments', function() { - it('throws', function(done) { - assert.throws(function() { - mquery().where('a').within().geometry({type:'a',coordinates:[]}, 2); - }, /Invalid argument/); - done(); - }); - }); - }); - - describe('intersects', function() { - it('must be used after where()', function(done) { - var m = mquery(); - assert.throws(function() { - m.intersects(); - }, /must be used after where/); - done(); - }); - - it('sets geo comparison to "$intersects"', function(done) { - var n = mquery().where('a').intersects(); - assert.equal('$geoIntersects', n._geoComparison); - done(); - }); - - it('is chainable', function() { - var m = mquery(); - assert.equal(m.where('a').intersects(), m); - }); - - it('calls geometry if argument quacks like geojson', function(done) { - var m = mquery(); - var o = { type: 'LineString', coordinates: [[0,1],[3,40]] }; - var ran = false; - - m.geometry = function(arg) { - ran = true; - assert.deepEqual(o, arg); - }; - - m.where('a').intersects(o); - assert.ok(ran); - - done(); - }); - - it('throws if argument is not geometry-like', function(done) { - var m = mquery().where('a'); - - assert.throws(function() { - m.intersects(null); - }, /Invalid argument/); - - assert.throws(function() { - m.intersects(undefined); - }, /Invalid argument/); - - assert.throws(function() { - m.intersects(false); - }, /Invalid argument/); - - assert.throws(function() { - m.intersects({}); - }, /Invalid argument/); - - assert.throws(function() { - m.intersects([]); - }, /Invalid argument/); - - assert.throws(function() { - m.intersects(function() {}); - }, /Invalid argument/); - - assert.throws(function() { - m.intersects(NaN); - }, /Invalid argument/); - - done(); - }); - }); - - describe('near', function() { - // near nearSphere - describe('with 0 args', function() { - it('is compatible with geometry()', function(done) { - var q = mquery().where('x').near().geometry({ type: 'Point', coordinates: [180, 11] }); - assert.deepEqual({ $near: {$geometry: {type:'Point', coordinates: [180,11]}}}, q._conditions.x); - done(); - }); - }); - - describe('with 1 arg', function() { - it('throws if not used after where()', function() { - assert.throws(function() { - mquery().near(1); - }, /must be used after where/); - }); - it('does not throw if used after where()', function() { - assert.doesNotThrow(function() { - mquery().where('loc').near({center:[1,1]}); - }); - }); - }); - describe('with > 2 args', function() { - it('throws', function() { - assert.throws(function() { - mquery().near(1,2,3); - }, /Invalid argument/); - }); - }); - - it('creates $geometry args for GeoJSON', function() { - var m = mquery().where('loc').near({ center: { type: 'Point', coordinates: [10,10] }}); - assert.deepEqual({ $near: {$geometry: {type:'Point', coordinates: [10,10]}}}, m._conditions.loc); - }); - - it('expects `center`', function() { - assert.throws(function() { - mquery().near('loc', { maxDistance: 3 }); - }, /center is required/); - assert.doesNotThrow(function() { - mquery().near('loc', { center: [3,4] }); - }); - }); - - it('accepts spherical conditions', function() { - var m = mquery().where('loc').near({ center: [1,2], spherical: true }); - assert.deepEqual(m._conditions, { loc: { $nearSphere: [1,2]}}); - }); - - it('is non-spherical by default', function() { - var m = mquery().where('loc').near({ center: [1,2] }); - assert.deepEqual(m._conditions, { loc: { $near: [1,2]}}); - }); - - it('supports maxDistance', function() { - var m = mquery().where('loc').near({ center: [1,2], maxDistance:4 }); - assert.deepEqual(m._conditions, { loc: { $near: [1,2], $maxDistance: 4}}); - }); - - it('supports minDistance', function() { - var m = mquery().where('loc').near({ center: [1,2], minDistance:4 }); - assert.deepEqual(m._conditions, { loc: { $near: [1,2], $minDistance: 4}}); - }); - - it('is chainable', function() { - var m = mquery().where('loc').near({ center: [1,2], maxDistance:4 }).find({ x: 1 }); - assert.deepEqual(m._conditions, { loc: { $near: [1,2], $maxDistance: 4}, x: 1}); - }); - - describe('supports passing GeoJSON, gh-13', function() { - it('with center', function() { - var m = mquery().where('loc').near({ - center: { type: 'Point', coordinates: [1,1] }, - maxDistance: 2 - }); - - var expect = { - loc: { - $near: { - $geometry: { - type: 'Point', - coordinates : [1,1] - }, - $maxDistance : 2 - } - } - }; - - assert.deepEqual(m._conditions, expect); - }); - }); - }); - - // fields - - describe('select', function() { - describe('with 0 args', function() { - it('is chainable', function() { - var m = mquery(); - assert.equal(m, m.select()); - }); - }); - - it('accepts an object', function() { - var o = { x: 1, y: 1 }; - var m = mquery().select(o); - assert.deepEqual(m._fields, o); - }); - - it('accepts a string', function() { - var o = 'x -y'; - var m = mquery().select(o); - assert.deepEqual(m._fields, { x: 1, y: 0 }); - }); - - it('does accept an array', function() { - var o = ['x', '-y']; - var m = mquery().select(o); - assert.deepEqual(m._fields, { x: 1, y: 0 }); - }); - - it('merges previous arguments', function() { - var o = { x: 1, y: 0, a: 1 }; - var m = mquery().select(o); - m.select('z -u w').select({ x: 0 }); - assert.deepEqual(m._fields, { - x: 0, - y: 0, - z: 1, - u: 0, - w: 1, - a: 1 - }); - }); - - it('rejects non-string, object, arrays', function() { - assert.throws(function() { - mquery().select(function() {}); - }, /Invalid select\(\) argument/); - }); - - it('accepts arguments objects', function() { - var m = mquery(); - function t() { - m.select(arguments); - assert.deepEqual(m._fields, { x: 1, y: 0 }); - } - t('x', '-y'); - }); - - noDistinct('select'); - }); - - describe('selected', function() { - it('returns true when fields have been selected', function(done) { - var m; - - m = mquery().select({ name: 1 }); - assert.ok(m.selected()); - - m = mquery().select('name'); - assert.ok(m.selected()); - - done(); - }); - - it('returns false when no fields have been selected', function(done) { - var m = mquery(); - assert.strictEqual(false, m.selected()); - done(); - }); - }); - - describe('selectedInclusively', function() { - describe('returns false', function() { - it('when no fields have been selected', function(done) { - assert.strictEqual(false, mquery().selectedInclusively()); - assert.equal(false, mquery().select({}).selectedInclusively()); - done(); - }); - it('when any fields have been excluded', function(done) { - assert.strictEqual(false, mquery().select('-name').selectedInclusively()); - assert.strictEqual(false, mquery().select({ name: 0 }).selectedInclusively()); - assert.strictEqual(false, mquery().select('name bio -_id').selectedInclusively()); - assert.strictEqual(false, mquery().select({ name: 1, _id: 0 }).selectedInclusively()); - done(); - }); - it('when using $meta', function(done) { - assert.strictEqual(false, mquery().select({ name: { $meta: 'textScore' } }).selectedInclusively()); - done(); - }); - }); - - describe('returns true', function() { - it('when fields have been included', function(done) { - assert.equal(true, mquery().select('name').selectedInclusively()); - assert.equal(true, mquery().select({ name:1 }).selectedInclusively()); - done(); - }); - }); - }); - - describe('selectedExclusively', function() { - describe('returns false', function() { - it('when no fields have been selected', function(done) { - assert.equal(false, mquery().selectedExclusively()); - assert.equal(false, mquery().select({}).selectedExclusively()); - done(); - }); - it('when fields have only been included', function(done) { - assert.equal(false, mquery().select('name').selectedExclusively()); - assert.equal(false, mquery().select({ name: 1 }).selectedExclusively()); - done(); - }); - }); - - describe('returns true', function() { - it('when any field has been excluded', function(done) { - assert.equal(true, mquery().select('-name').selectedExclusively()); - assert.equal(true, mquery().select({ name:0 }).selectedExclusively()); - assert.equal(true, mquery().select('-_id').selectedExclusively()); - assert.strictEqual(true, mquery().select('name bio -_id').selectedExclusively()); - assert.strictEqual(true, mquery().select({ name: 1, _id: 0 }).selectedExclusively()); - done(); - }); - }); - }); - - describe('slice', function() { - describe('with 0 args', function() { - it('is chainable', function() { - var m = mquery(); - assert.equal(m, m.slice()); - }); - it('is a noop', function() { - var m = mquery().slice(); - assert.deepEqual(m._fields, undefined); - }); - }); - - describe('with 1 arg', function() { - it('throws if not called after where()', function() { - assert.throws(function() { - mquery().slice(1); - }, /must be used after where/); - assert.doesNotThrow(function() { - mquery().where('a').slice(1); - }); - }); - it('that is a number', function() { - var query = mquery(); - query.where('collection').slice(5); - assert.deepEqual(query._fields, {collection: {$slice: 5}}); - }); - it('that is an array', function() { - var query = mquery(); - query.where('collection').slice([5,10]); - assert.deepEqual(query._fields, {collection: {$slice: [5,10]}}); - }); - it('that is an object', function() { - var query = mquery(); - query.slice({ collection: [5, 10] }); - assert.deepEqual(query._fields, {collection: {$slice: [5,10]}}); - }); - }); - - describe('with 2 args', function() { - describe('and first is a number', function() { - it('throws if not called after where', function() { - assert.throws(function() { - mquery().slice(2,3); - }, /must be used after where/); - }); - it('does not throw if used after where', function() { - var query = mquery(); - query.where('collection').slice(2,3); - assert.deepEqual(query._fields, {collection: {$slice: [2,3]}}); - }); - }); - it('and first is not a number', function() { - var query = mquery().slice('collection', [-5, 2]); - assert.deepEqual(query._fields, {collection: {$slice: [-5,2]}}); - }); - }); - - describe('with 3 args', function() { - it('works', function() { - var query = mquery(); - query.slice('collection', 14, 10); - assert.deepEqual(query._fields, {collection: {$slice: [14, 10]}}); - }); - }); - - noDistinct('slice'); - no('count', 'slice'); - }); - - // options - - describe('sort', function() { - describe('with 0 args', function() { - it('chains', function() { - var m = mquery(); - assert.equal(m, m.sort()); - }); - it('has no affect', function() { - var m = mquery(); - assert.equal(m.options.sort, undefined); - }); - }); - - it('works', function() { - var query = mquery(); - query.sort('a -c b'); - assert.deepEqual(query.options.sort, { a : 1, b: 1, c : -1}); - - query = mquery(); - query.sort({'a': 1, 'c': -1, 'b': 'asc', e: 'descending', f: 'ascending'}); - assert.deepEqual(query.options.sort, {'a': 1, 'c': -1, 'b': 1, 'e': -1, 'f': 1}); - - query = mquery(); - query.sort([['a', -1], ['c', 1], ['b', 'desc'], ['e', 'ascending'], ['f', 'descending']]); - assert.deepEqual(query.options.sort, [['a', -1], ['c', 1], ['b', -1], ['e', 1], ['f', -1]]); - - query = mquery(); - var e = undefined; - try { - query.sort([['a', 1], { 'b': 5 }]); - } catch (err) { - e = err; - } - assert.ok(e, 'uh oh. no error was thrown'); - assert.equal(e.message, 'Invalid sort() argument, must be array of arrays'); - - query = mquery(); - e = undefined; - - try { - query.sort('a', 1, 'c', -1, 'b', 1); - } catch (err) { - e = err; - } - assert.ok(e, 'uh oh. no error was thrown'); - assert.equal(e.message, 'Invalid sort() argument. Must be a string, object, or array.'); - }); - - it('handles $meta sort options', function() { - var query = mquery(); - query.sort({ score: { $meta : 'textScore' } }); - assert.deepEqual(query.options.sort, { score : { $meta : 'textScore' } }); - }); - - it('array syntax', function() { - var query = mquery(); - query.sort([['field', 1], ['test', -1]]); - assert.deepEqual(query.options.sort, [['field', 1], ['test', -1]]); - }); - - it('throws with mixed array/object syntax', function() { - var query = mquery(); - assert.throws(function() { - query.sort({ field: 1 }).sort([['test', -1]]); - }, /Can't mix sort syntaxes/); - assert.throws(function() { - query.sort([['field', 1]]).sort({ test: 1 }); - }, /Can't mix sort syntaxes/); - }); - - it('works with maps', function() { - if (typeof Map === 'undefined') { - return this.skip(); - } - var query = mquery(); - query.sort(new Map().set('field', 1).set('test', -1)); - assert.deepEqual(query.options.sort, new Map().set('field', 1).set('test', -1)); - }); - }); - - function simpleOption(type, options) { - describe(type, function() { - it('sets the ' + type + ' option', function() { - var m = mquery()[type](2); - var optionName = options.name || type; - assert.equal(2, m.options[optionName]); - }); - it('is chainable', function() { - var m = mquery(); - assert.equal(m[type](3), m); - }); - - if (!options.distinct) noDistinct(type); - if (!options.count) no('count', type); - }); - } - - var negated = { - limit: {distinct: false, count: true}, - skip: {distinct: false, count: true}, - maxScan: {distinct: false, count: false}, - batchSize: {distinct: false, count: false}, - maxTime: {distinct: true, count: true, name: 'maxTimeMS' }, - comment: {distinct: false, count: false} - }; - Object.keys(negated).forEach(function(key) { - simpleOption(key, negated[key]); - }); - - describe('snapshot', function() { - it('works', function() { - var query; - - query = mquery(); - query.snapshot(); - assert.equal(true, query.options.snapshot); - - query = mquery(); - query.snapshot(true); - assert.equal(true, query.options.snapshot); - - query = mquery(); - query.snapshot(false); - assert.equal(false, query.options.snapshot); - }); - noDistinct('snapshot'); - no('count', 'snapshot'); - }); - - describe('hint', function() { - it('accepts an object', function() { - var query2 = mquery(); - query2.hint({'a': 1, 'b': -1}); - assert.deepEqual(query2.options.hint, {'a': 1, 'b': -1}); - }); - - it('accepts a string', function() { - var query2 = mquery(); - query2.hint('a'); - assert.deepEqual(query2.options.hint, 'a'); - }); - - it('rejects everything else', function() { - assert.throws(function() { - mquery().hint(['c']); - }, /Invalid hint./); - assert.throws(function() { - mquery().hint(1); - }, /Invalid hint./); - }); - - describe('does not have side affects', function() { - it('on invalid arg', function() { - var m = mquery(); - try { - m.hint(1); - } catch (err) { - // ignore - } - assert.equal(undefined, m.options.hint); - }); - it('on missing arg', function() { - var m = mquery().hint(); - assert.equal(undefined, m.options.hint); - }); - }); - - noDistinct('hint'); - }); - - describe('j', function() { - it('works', function() { - var m = mquery().j(true); - assert.equal(true, m.options.j); - }); - }); - - describe('slaveOk', function() { - it('works', function() { - var query; - - query = mquery(); - query.slaveOk(); - assert.equal(true, query.options.slaveOk); - - query = mquery(); - query.slaveOk(true); - assert.equal(true, query.options.slaveOk); - - query = mquery(); - query.slaveOk(false); - assert.equal(false, query.options.slaveOk); - }); - }); - - describe('read', function() { - it('sets associated readPreference option', function() { - var m = mquery(); - m.read('p'); - assert.equal('primary', m.options.readPreference); - }); - it('is chainable', function() { - var m = mquery(); - assert.equal(m, m.read('sp')); - }); - }); - - describe('readConcern', function() { - it('sets associated readConcern option', function() { - var m; - - m = mquery(); - m.readConcern('s'); - assert.deepEqual({ level: 'snapshot' }, m.options.readConcern); - - m = mquery(); - m.r('local'); - assert.deepEqual({ level: 'local' }, m.options.readConcern); - }); - it('is chainable', function() { - var m = mquery(); - assert.equal(m, m.readConcern('lz')); - }); - }); - - describe('tailable', function() { - it('works', function() { - var query; - - query = mquery(); - query.tailable(); - assert.equal(true, query.options.tailable); - - query = mquery(); - query.tailable(true); - assert.equal(true, query.options.tailable); - - query = mquery(); - query.tailable(false); - assert.equal(false, query.options.tailable); - }); - it('is chainable', function() { - var m = mquery(); - assert.equal(m, m.tailable()); - }); - noDistinct('tailable'); - no('count', 'tailable'); - }); - - describe('writeConcern', function() { - it('sets associated writeConcern option', function() { - var m; - m = mquery(); - m.writeConcern('majority'); - assert.equal('majority', m.options.w); - - m = mquery(); - m.writeConcern('m'); // m is alias of majority - assert.equal('majority', m.options.w); - - m = mquery(); - m.writeConcern(1); - assert.equal(1, m.options.w); - }); - it('accepts object', function() { - var m; - - m = mquery().writeConcern({ w: 'm', j: true, wtimeout: 1000 }); - assert.equal('m', m.options.w); // check it does not convert m to majority - assert.equal(true, m.options.j); - assert.equal(1000, m.options.wtimeout); - - m = mquery().w('m').w({j: false, wtimeout: 0 }); - assert.equal('majority', m.options.w); - assert.strictEqual(false, m.options.j); - assert.strictEqual(0, m.options.wtimeout); - }); - it('is chainable', function() { - var m = mquery(); - assert.equal(m, m.writeConcern('majority')); - }); - }); - - // query utilities - - describe('merge', function() { - describe('with falsy arg', function() { - it('returns itself', function() { - var m = mquery(); - assert.equal(m, m.merge()); - assert.equal(m, m.merge(null)); - assert.equal(m, m.merge(0)); - }); - }); - describe('with an argument', function() { - describe('that is not a query or plain object', function() { - it('throws', function() { - assert.throws(function() { - mquery().merge([]); - }, /Invalid argument/); - assert.throws(function() { - mquery().merge('merge'); - }, /Invalid argument/); - assert.doesNotThrow(function() { - mquery().merge({}); - }, /Invalid argument/); - }); - }); - - describe('that is a query', function() { - it('merges conditions, field selection, and options', function() { - var m = mquery({ x: 'hi' }, { select: 'x y', another: true }); - var n = mquery().merge(m); - assert.deepEqual(n._conditions, m._conditions); - assert.deepEqual(n._fields, m._fields); - assert.deepEqual(n.options, m.options); - }); - it('clones update arguments', function(done) { - var original = { $set: { iTerm: true }}; - var m = mquery().update(original); - var n = mquery().merge(m); - m.update({ $set: { x: 2 }}); - assert.notDeepEqual(m._update, n._update); - done(); - }); - it('is chainable', function() { - var m = mquery({ x: 'hi' }); - var n = mquery(); - assert.equal(n, n.merge(m)); - }); - }); - - describe('that is an object', function() { - it('merges', function() { - var m = { x: 'hi' }; - var n = mquery().merge(m); - assert.deepEqual(n._conditions, { x: 'hi' }); - }); - it('clones update arguments', function(done) { - var original = { $set: { iTerm: true }}; - var m = mquery().update(original); - var n = mquery().merge(original); - m.update({ $set: { x: 2 }}); - assert.notDeepEqual(m._update, n._update); - done(); - }); - it('is chainable', function() { - var m = { x: 'hi' }; - var n = mquery(); - assert.equal(n, n.merge(m)); - }); - }); - }); - }); - - // queries - - describe('find', function() { - describe('with no callback', function() { - it('does not execute', function() { - var m = mquery(); - assert.doesNotThrow(function() { - m.find(); - }); - assert.doesNotThrow(function() { - m.find({ x: 1 }); - }); - }); - }); - - it('is chainable', function() { - var m = mquery().find({ x: 1 }).find().find({ y: 2 }); - assert.deepEqual(m._conditions, {x:1,y:2}); - }); - - it('merges other queries', function() { - var m = mquery({ name: 'mquery' }); - m.tailable(); - m.select('_id'); - var a = mquery().find(m); - assert.deepEqual(a._conditions, m._conditions); - assert.deepEqual(a.options, m.options); - assert.deepEqual(a._fields, m._fields); - }); - - describe('executes', function() { - before(function(done) { - col.insert({ name: 'mquery' }, { safe: true }, done); - }); - - after(function(done) { - col.remove({ name: 'mquery' }, done); - }); - - it('when criteria is passed with a callback', function(done) { - mquery(col).find({ name: 'mquery' }, function(err, docs) { - assert.ifError(err); - assert.equal(1, docs.length); - done(); - }); - }); - it('when Query is passed with a callback', function(done) { - var m = mquery({ name: 'mquery' }); - mquery(col).find(m, function(err, docs) { - assert.ifError(err); - assert.equal(1, docs.length); - done(); - }); - }); - it('when just a callback is passed', function(done) { - mquery({ name: 'mquery' }).collection(col).find(function(err, docs) { - assert.ifError(err); - assert.equal(1, docs.length); - done(); - }); - }); - }); - }); - - describe('findOne', function() { - describe('with no callback', function() { - it('does not execute', function() { - var m = mquery(); - assert.doesNotThrow(function() { - m.findOne(); - }); - assert.doesNotThrow(function() { - m.findOne({ x: 1 }); - }); - }); - }); - - it('is chainable', function() { - var m = mquery(); - var n = m.findOne({ x: 1 }).findOne().findOne({ y: 2 }); - assert.equal(m, n); - assert.deepEqual(m._conditions, {x:1,y:2}); - assert.equal('findOne', m.op); - }); - - it('merges other queries', function() { - var m = mquery({ name: 'mquery' }); - m.read('nearest'); - m.select('_id'); - var a = mquery().findOne(m); - assert.deepEqual(a._conditions, m._conditions); - assert.deepEqual(a.options, m.options); - assert.deepEqual(a._fields, m._fields); - }); - - describe('executes', function() { - before(function(done) { - col.insert({ name: 'mquery findone' }, { safe: true }, done); - }); - - after(function(done) { - col.remove({ name: 'mquery findone' }, done); - }); - - it('when criteria is passed with a callback', function(done) { - mquery(col).findOne({ name: 'mquery findone' }, function(err, doc) { - assert.ifError(err); - assert.ok(doc); - assert.equal('mquery findone', doc.name); - done(); - }); - }); - it('when Query is passed with a callback', function(done) { - var m = mquery(col).where({ name: 'mquery findone' }); - mquery(col).findOne(m, function(err, doc) { - assert.ifError(err); - assert.ok(doc); - assert.equal('mquery findone', doc.name); - done(); - }); - }); - it('when just a callback is passed', function(done) { - mquery({ name: 'mquery findone' }).collection(col).findOne(function(err, doc) { - assert.ifError(err); - assert.ok(doc); - assert.equal('mquery findone', doc.name); - done(); - }); - }); - }); - }); - - describe('count', function() { - describe('with no callback', function() { - it('does not execute', function() { - var m = mquery(); - assert.doesNotThrow(function() { - m.count(); - }); - assert.doesNotThrow(function() { - m.count({ x: 1 }); - }); - }); - }); - - it('is chainable', function() { - var m = mquery(); - var n = m.count({ x: 1 }).count().count({ y: 2 }); - assert.equal(m, n); - assert.deepEqual(m._conditions, {x:1,y:2}); - assert.equal('count', m.op); - }); - - it('merges other queries', function() { - var m = mquery({ name: 'mquery' }); - m.read('nearest'); - m.select('_id'); - var a = mquery().count(m); - assert.deepEqual(a._conditions, m._conditions); - assert.deepEqual(a.options, m.options); - assert.deepEqual(a._fields, m._fields); - }); - - describe('executes', function() { - before(function(done) { - col.insert({ name: 'mquery count' }, { safe: true }, done); - }); - - after(function(done) { - col.remove({ name: 'mquery count' }, done); - }); - - it('when criteria is passed with a callback', function(done) { - mquery(col).count({ name: 'mquery count' }, function(err, count) { - assert.ifError(err); - assert.ok(count); - assert.ok(1 === count); - done(); - }); - }); - it('when Query is passed with a callback', function(done) { - var m = mquery({ name: 'mquery count' }); - mquery(col).count(m, function(err, count) { - assert.ifError(err); - assert.ok(count); - assert.ok(1 === count); - done(); - }); - }); - it('when just a callback is passed', function(done) { - mquery({ name: 'mquery count' }).collection(col).count(function(err, count) { - assert.ifError(err); - assert.ok(1 === count); - done(); - }); - }); - }); - - describe('validates its option', function() { - it('sort', function(done) { - assert.doesNotThrow(function() { - mquery().sort('x').count(); - }); - done(); - }); - - it('select', function(done) { - assert.throws(function() { - mquery().select('x').count(); - }, /field selection and slice cannot be used with count/); - done(); - }); - - it('slice', function(done) { - assert.throws(function() { - mquery().where('x').slice(-3).count(); - }, /field selection and slice cannot be used with count/); - done(); - }); - - it('limit', function(done) { - assert.doesNotThrow(function() { - mquery().limit(3).count(); - }); - done(); - }); - - it('skip', function(done) { - assert.doesNotThrow(function() { - mquery().skip(3).count(); - }); - done(); - }); - - it('batchSize', function(done) { - assert.throws(function() { - mquery({}, { batchSize: 3 }).count(); - }, /batchSize cannot be used with count/); - done(); - }); - - it('comment', function(done) { - assert.throws(function() { - mquery().comment('mquery').count(); - }, /comment cannot be used with count/); - done(); - }); - - it('maxScan', function(done) { - assert.throws(function() { - mquery().maxScan(300).count(); - }, /maxScan cannot be used with count/); - done(); - }); - - it('snapshot', function(done) { - assert.throws(function() { - mquery().snapshot().count(); - }, /snapshot cannot be used with count/); - done(); - }); - - it('tailable', function(done) { - assert.throws(function() { - mquery().tailable().count(); - }, /tailable cannot be used with count/); - done(); - }); - }); - }); - - describe('distinct', function() { - describe('with no callback', function() { - it('does not execute', function() { - var m = mquery(); - assert.doesNotThrow(function() { - m.distinct(); - }); - assert.doesNotThrow(function() { - m.distinct('name'); - }); - assert.doesNotThrow(function() { - m.distinct({ name: 'mquery distinct' }); - }); - assert.doesNotThrow(function() { - m.distinct({ name: 'mquery distinct' }, 'name'); - }); - }); - }); - - it('is chainable', function() { - var m = mquery({x:1}).distinct('name'); - var n = m.distinct({y:2}); - assert.equal(m, n); - assert.deepEqual(n._conditions, {x:1, y:2}); - assert.equal('name', n._distinct); - assert.equal('distinct', n.op); - }); - - it('overwrites field', function() { - var m = mquery({ name: 'mquery' }).distinct('name'); - m.distinct('rename'); - assert.equal(m._distinct, 'rename'); - m.distinct({x:1}, 'renamed'); - assert.equal(m._distinct, 'renamed'); - }); - - it('merges other queries', function() { - var m = mquery().distinct({ name: 'mquery' }, 'age'); - m.read('nearest'); - var a = mquery().distinct(m); - assert.deepEqual(a._conditions, m._conditions); - assert.deepEqual(a.options, m.options); - assert.deepEqual(a._fields, m._fields); - assert.deepEqual(a._distinct, m._distinct); - }); - - describe('executes', function() { - before(function(done) { - col.insert({ name: 'mquery distinct', age: 1 }, { safe: true }, done); - }); - - after(function(done) { - col.remove({ name: 'mquery distinct' }, done); - }); - - it('when distinct arg is passed with a callback', function(done) { - mquery(col).distinct('distinct', function(err, doc) { - assert.ifError(err); - assert.ok(doc); - done(); - }); - }); - describe('when criteria is passed with a callback', function() { - it('if distinct arg was declared', function(done) { - mquery(col).distinct('age').distinct({ name: 'mquery distinct' }, function(err, doc) { - assert.ifError(err); - assert.ok(doc); - done(); - }); - }); - it('but not if distinct arg was not declared', function() { - assert.throws(function() { - mquery(col).distinct({ name: 'mquery distinct' }, function() {}); - }, /No value for `distinct`/); - }); - }); - describe('when Query is passed with a callback', function() { - var m = mquery({ name: 'mquery distinct' }); - it('if distinct arg was declared', function(done) { - mquery(col).distinct('age').distinct(m, function(err, doc) { - assert.ifError(err); - assert.ok(doc); - done(); - }); - }); - it('but not if distinct arg was not declared', function() { - assert.throws(function() { - mquery(col).distinct(m, function() {}); - }, /No value for `distinct`/); - }); - }); - describe('when just a callback is passed', function() { - it('if distinct arg was declared', function(done) { - var m = mquery({ name: 'mquery distinct' }); - m.collection(col); - m.distinct('age'); - m.distinct(function(err, doc) { - assert.ifError(err); - assert.ok(doc); - done(); - }); - }); - it('but not if no distinct arg was declared', function() { - var m = mquery(); - m.collection(col); - assert.throws(function() { - m.distinct(function() {}); - }, /No value for `distinct`/); - }); - }); - }); - - describe('validates its option', function() { - it('sort', function(done) { - assert.throws(function() { - mquery().sort('x').distinct(); - }, /sort cannot be used with distinct/); - done(); - }); - - it('select', function(done) { - assert.throws(function() { - mquery().select('x').distinct(); - }, /field selection and slice cannot be used with distinct/); - done(); - }); - - it('slice', function(done) { - assert.throws(function() { - mquery().where('x').slice(-3).distinct(); - }, /field selection and slice cannot be used with distinct/); - done(); - }); - - it('limit', function(done) { - assert.throws(function() { - mquery().limit(3).distinct(); - }, /limit cannot be used with distinct/); - done(); - }); - - it('skip', function(done) { - assert.throws(function() { - mquery().skip(3).distinct(); - }, /skip cannot be used with distinct/); - done(); - }); - - it('batchSize', function(done) { - assert.throws(function() { - mquery({}, { batchSize: 3 }).distinct(); - }, /batchSize cannot be used with distinct/); - done(); - }); - - it('comment', function(done) { - assert.throws(function() { - mquery().comment('mquery').distinct(); - }, /comment cannot be used with distinct/); - done(); - }); - - it('maxScan', function(done) { - assert.throws(function() { - mquery().maxScan(300).distinct(); - }, /maxScan cannot be used with distinct/); - done(); - }); - - it('snapshot', function(done) { - assert.throws(function() { - mquery().snapshot().distinct(); - }, /snapshot cannot be used with distinct/); - done(); - }); - - it('hint', function(done) { - assert.throws(function() { - mquery().hint({ x: 1 }).distinct(); - }, /hint cannot be used with distinct/); - done(); - }); - - it('tailable', function(done) { - assert.throws(function() { - mquery().tailable().distinct(); - }, /tailable cannot be used with distinct/); - done(); - }); - }); - }); - - describe('update', function() { - describe('with no callback', function() { - it('does not execute', function() { - var m = mquery(); - assert.doesNotThrow(function() { - m.update({ name: 'old' }, { name: 'updated' }, { multi: true }); - }); - assert.doesNotThrow(function() { - m.update({ name: 'old' }, { name: 'updated' }); - }); - assert.doesNotThrow(function() { - m.update({ name: 'updated' }); - }); - assert.doesNotThrow(function() { - m.update(); - }); - }); - }); - - it('is chainable', function() { - var m = mquery({x:1}).update({ y: 2 }); - var n = m.where({y:2}); - assert.equal(m, n); - assert.deepEqual(n._conditions, {x:1, y:2}); - assert.deepEqual({ y: 2 }, n._update); - assert.equal('update', n.op); - }); - - it('merges update doc arg', function() { - var a = [1,2]; - var m = mquery().where({ name: 'mquery' }).update({ x: 'stuff', a: a }); - m.update({ z: 'stuff' }); - assert.deepEqual(m._update, { z: 'stuff', x: 'stuff', a: a }); - assert.deepEqual(m._conditions, { name: 'mquery' }); - assert.ok(!m.options.overwrite); - m.update({}, { z: 'renamed' }, { overwrite: true }); - assert.ok(m.options.overwrite === true); - assert.deepEqual(m._conditions, { name: 'mquery' }); - assert.deepEqual(m._update, { z: 'renamed', x: 'stuff', a: a }); - a.push(3); - assert.notDeepEqual(m._update, { z: 'renamed', x: 'stuff', a: a }); - }); - - it('merges other options', function() { - var m = mquery(); - m.setOptions({ overwrite: true }); - m.update({ age: 77 }, { name: 'pagemill' }, { multi: true }); - assert.deepEqual({ age: 77 }, m._conditions); - assert.deepEqual({ name: 'pagemill' }, m._update); - assert.deepEqual({ overwrite: true, multi: true }, m.options); - }); - - describe('executes', function() { - var id; - before(function(done) { - col.insert({ name: 'mquery update', age: 1 }, { safe: true }, function(err, res) { - id = res.insertedIds[0]; - done(); - }); - }); - - after(function(done) { - col.remove({ _id: id }, done); - }); - - describe('when conds + doc + opts + callback passed', function() { - it('works', function(done) { - var m = mquery(col).where({ _id: id }); - m.update({}, { name: 'Sparky' }, { safe: true }, function(err, res) { - assert.ifError(err); - assert.equal(res.result.n, 1); - m.findOne(function(err, doc) { - assert.ifError(err); - assert.equal(doc.name, 'Sparky'); - done(); - }); - }); - }); - }); - - describe('when conds + doc + callback passed', function() { - it('works', function(done) { - var m = mquery(col).update({ _id: id }, { name: 'fairgrounds' }, function(err, num) { - assert.ifError(err); - assert.ok(1, num); - m.findOne(function(err, doc) { - assert.ifError(err); - assert.equal(doc.name, 'fairgrounds'); - done(); - }); - }); - }); - }); - - describe('when doc + callback passed', function() { - it('works', function(done) { - var m = mquery(col).where({ _id: id }).update({ name: 'changed' }, function(err, num) { - assert.ifError(err); - assert.ok(1, num); - m.findOne(function(err, doc) { - assert.ifError(err); - assert.equal(doc.name, 'changed'); - done(); - }); - }); - }); - }); - - describe('when just callback passed', function() { - it('works', function(done) { - var m = mquery(col).where({ _id: id }); - m.setOptions({ safe: true }); - m.update({ name: 'Frankenweenie' }); - m.update(function(err, res) { - assert.ifError(err); - assert.equal(res.result.n, 1); - m.findOne(function(err, doc) { - assert.ifError(err); - assert.equal(doc.name, 'Frankenweenie'); - done(); - }); - }); - }); - }); - - describe('without a callback', function() { - it('when forced by exec()', function(done) { - var m = mquery(col).where({ _id: id }); - m.setOptions({ safe: true, multi: true }); - m.update({ name: 'forced' }); - - var update = m._collection.update; - m._collection.update = function(conds, doc, opts) { - m._collection.update = update; - - assert.ok(opts.safe); - assert.ok(true === opts.multi); - assert.equal('forced', doc.$set.name); - done(); - }; - - m.exec(); - }); - }); - - describe('except when update doc is empty and missing overwrite flag', function() { - it('works', function(done) { - var m = mquery(col).where({ _id: id }); - m.setOptions({ safe: true }); - m.update({ }, function(err, num) { - assert.ifError(err); - assert.ok(0 === num); - setTimeout(function() { - m.findOne(function(err, doc) { - assert.ifError(err); - assert.equal(3, mquery.utils.keys(doc).length); - assert.equal(id, doc._id.toString()); - assert.equal('Frankenweenie', doc.name); - done(); - }); - }, 300); - }); - }); - }); - - describe('when update doc is set with overwrite flag', function() { - it('works', function(done) { - var m = mquery(col).where({ _id: id }); - m.setOptions({ safe: true, overwrite: true }); - m.update({ all: 'yep', two: 2 }, function(err, res) { - assert.ifError(err); - assert.equal(res.result.n, 1); - m.findOne(function(err, doc) { - assert.ifError(err); - assert.equal(3, mquery.utils.keys(doc).length); - assert.equal('yep', doc.all); - assert.equal(2, doc.two); - assert.equal(id, doc._id.toString()); - done(); - }); - }); - }); - }); - - describe('when update doc is empty with overwrite flag', function() { - it('works', function(done) { - var m = mquery(col).where({ _id: id }); - m.setOptions({ safe: true, overwrite: true }); - m.update({ }, function(err, res) { - assert.ifError(err); - assert.equal(res.result.n, 1); - m.findOne(function(err, doc) { - assert.ifError(err); - assert.equal(1, mquery.utils.keys(doc).length); - assert.equal(id, doc._id.toString()); - done(); - }); - }); - }); - }); - - describe('when boolean (true) - exec()', function() { - it('works', function(done) { - var m = mquery(col).where({ _id: id }); - m.update({ name: 'bool' }).update(true); - setTimeout(function() { - m.findOne(function(err, doc) { - assert.ifError(err); - assert.ok(doc); - assert.equal('bool', doc.name); - done(); - }); - }, 300); - }); - }); - }); - }); - - describe('remove', function() { - describe('with 0 args', function() { - var name = 'remove: no args test'; - before(function(done) { - col.insert({ name: name }, { safe: true }, done); - }); - after(function(done) { - col.remove({ name: name }, { safe: true }, done); - }); - - it('does not execute', function(done) { - var remove = col.remove; - col.remove = function() { - col.remove = remove; - done(new Error('remove executed!')); - }; - - mquery(col).where({ name: name }).remove(); - setTimeout(function() { - col.remove = remove; - done(); - }, 10); - }); - - it('chains', function() { - var m = mquery(); - assert.equal(m, m.remove()); - }); - }); - - describe('with 1 argument', function() { - var name = 'remove: 1 arg test'; - before(function(done) { - col.insert({ name: name }, { safe: true }, done); - }); - after(function(done) { - col.remove({ name: name }, { safe: true }, done); - }); - - describe('that is a', function() { - it('plain object', function() { - var m = mquery(col).remove({ name: 'Whiskers' }); - m.remove({ color: '#fff' }); - assert.deepEqual({ name: 'Whiskers', color: '#fff' }, m._conditions); - }); - - it('query', function() { - var q = mquery({ color: '#fff' }); - var m = mquery(col).remove({ name: 'Whiskers' }); - m.remove(q); - assert.deepEqual({ name: 'Whiskers', color: '#fff' }, m._conditions); - }); - - it('function', function(done) { - mquery(col, { safe: true }).where({name: name}).remove(function(err) { - assert.ifError(err); - mquery(col).findOne({ name: name }, function(err, doc) { - assert.ifError(err); - assert.equal(null, doc); - done(); - }); - }); - }); - - it('boolean (true) - execute', function(done) { - col.insert({ name: name }, { safe: true }, function(err) { - assert.ifError(err); - mquery(col).findOne({ name: name }, function(err, doc) { - assert.ifError(err); - assert.ok(doc); - mquery(col).remove(true); - setTimeout(function() { - mquery(col).find(function(err, docs) { - assert.ifError(err); - assert.ok(docs); - assert.equal(0, docs.length); - done(); - }); - }, 300); - }); - }); - }); - }); - }); - - describe('with 2 arguments', function() { - var name = 'remove: 2 arg test'; - beforeEach(function(done) { - col.remove({}, { safe: true }, function(err) { - assert.ifError(err); - col.insert([{ name: 'shelly' }, { name: name }], { safe: true }, function(err) { - assert.ifError(err); - mquery(col).find(function(err, docs) { - assert.ifError(err); - assert.equal(2, docs.length); - done(); - }); - }); - }); - }); - - describe('plain object + callback', function() { - it('works', function(done) { - mquery(col).remove({ name: name }, function(err) { - assert.ifError(err); - mquery(col).find(function(err, docs) { - assert.ifError(err); - assert.ok(docs); - assert.equal(1, docs.length); - assert.equal('shelly', docs[0].name); - done(); - }); - }); - }); - }); - - describe('mquery + callback', function() { - it('works', function(done) { - var m = mquery({ name: name }); - mquery(col).remove(m, function(err) { - assert.ifError(err); - mquery(col).find(function(err, docs) { - assert.ifError(err); - assert.ok(docs); - assert.equal(1, docs.length); - assert.equal('shelly', docs[0].name); - done(); - }); - }); - }); - }); - }); - }); - - function validateFindAndModifyOptions(method) { - describe('validates its option', function() { - it('sort', function(done) { - assert.doesNotThrow(function() { - mquery().sort('x')[method](); - }); - done(); - }); - - it('select', function(done) { - assert.doesNotThrow(function() { - mquery().select('x')[method](); - }); - done(); - }); - - it('limit', function(done) { - assert.throws(function() { - mquery().limit(3)[method](); - }, new RegExp('limit cannot be used with ' + method)); - done(); - }); - - it('skip', function(done) { - assert.throws(function() { - mquery().skip(3)[method](); - }, new RegExp('skip cannot be used with ' + method)); - done(); - }); - - it('batchSize', function(done) { - assert.throws(function() { - mquery({}, { batchSize: 3 })[method](); - }, new RegExp('batchSize cannot be used with ' + method)); - done(); - }); - - it('maxScan', function(done) { - assert.throws(function() { - mquery().maxScan(300)[method](); - }, new RegExp('maxScan cannot be used with ' + method)); - done(); - }); - - it('snapshot', function(done) { - assert.throws(function() { - mquery().snapshot()[method](); - }, new RegExp('snapshot cannot be used with ' + method)); - done(); - }); - - it('hint', function(done) { - assert.throws(function() { - mquery().hint({ x: 1 })[method](); - }, new RegExp('hint cannot be used with ' + method)); - done(); - }); - - it('tailable', function(done) { - assert.throws(function() { - mquery().tailable()[method](); - }, new RegExp('tailable cannot be used with ' + method)); - done(); - }); - - it('comment', function(done) { - assert.throws(function() { - mquery().comment('mquery')[method](); - }, new RegExp('comment cannot be used with ' + method)); - done(); - }); - }); - } - - describe('findOneAndUpdate', function() { - var name = 'findOneAndUpdate + fn'; - - validateFindAndModifyOptions('findOneAndUpdate'); - - describe('with 0 args', function() { - it('makes no changes', function() { - var m = mquery(); - var n = m.findOneAndUpdate(); - assert.deepEqual(m, n); - }); - }); - describe('with 1 arg', function() { - describe('that is an object', function() { - it('updates the doc', function() { - var m = mquery(); - var n = m.findOneAndUpdate({ $set: { name: '1 arg' }}); - assert.deepEqual(n._update, { $set: { name: '1 arg' }}); - }); - }); - describe('that is a query', function() { - it('updates the doc', function() { - var m = mquery({ name: name }).update({ x: 1 }); - var n = mquery().findOneAndUpdate(m); - assert.deepEqual(n._update, { x: 1 }); - }); - }); - it('that is a function', function(done) { - col.insert({ name: name }, { safe: true }, function(err) { - assert.ifError(err); - var m = mquery({ name: name }).collection(col); - name = '1 arg'; - var n = m.update({ $set: { name: name }}); - n.findOneAndUpdate(function(err, res) { - assert.ifError(err); - assert.ok(res.value); - assert.equal(name, res.value.name); - done(); - }); - }); - }); - }); - describe('with 2 args', function() { - it('conditions + update', function() { - var m = mquery(col); - m.findOneAndUpdate({ name: name }, { age: 100 }); - assert.deepEqual({ name: name }, m._conditions); - assert.deepEqual({ age: 100 }, m._update); - }); - it('query + update', function() { - var n = mquery({ name: name }); - var m = mquery(col); - m.findOneAndUpdate(n, { age: 100 }); - assert.deepEqual({ name: name }, m._conditions); - assert.deepEqual({ age: 100 }, m._update); - }); - it('update + callback', function(done) { - var m = mquery(col).where({ name: name }); - m.findOneAndUpdate({}, { $inc: { age: 10 }}, { new: true }, function(err, res) { - assert.ifError(err); - assert.equal(10, res.value.age); - done(); - }); - }); - }); - describe('with 3 args', function() { - it('conditions + update + options', function() { - var m = mquery(); - var n = m.findOneAndUpdate({ name: name }, { works: true }, { new: false }); - assert.deepEqual({ name: name}, n._conditions); - assert.deepEqual({ works: true }, n._update); - assert.deepEqual({ new: false }, n.options); - }); - it('conditions + update + callback', function(done) { - var m = mquery(col); - m.findOneAndUpdate({ name: name }, { works: true }, { new: true }, function(err, res) { - assert.ifError(err); - assert.ok(res.value); - assert.equal(name, res.value.name); - assert.ok(true === res.value.works); - done(); - }); - }); - }); - describe('with 4 args', function() { - it('conditions + update + options + callback', function(done) { - var m = mquery(col); - m.findOneAndUpdate({ name: name }, { works: false }, { new: false }, function(err, res) { - assert.ifError(err); - assert.ok(res.value); - assert.equal(name, res.value.name); - assert.ok(true === res.value.works); - done(); - }); - }); - }); - }); - - describe('findOneAndRemove', function() { - var name = 'findOneAndRemove'; - - validateFindAndModifyOptions('findOneAndRemove'); - - describe('with 0 args', function() { - it('makes no changes', function() { - var m = mquery(); - var n = m.findOneAndRemove(); - assert.deepEqual(m, n); - }); - }); - describe('with 1 arg', function() { - describe('that is an object', function() { - it('updates the doc', function() { - var m = mquery(); - var n = m.findOneAndRemove({ name: '1 arg' }); - assert.deepEqual(n._conditions, { name: '1 arg' }); - }); - }); - describe('that is a query', function() { - it('updates the doc', function() { - var m = mquery({ name: name }); - var n = m.findOneAndRemove(m); - assert.deepEqual(n._conditions, { name: name }); - }); - }); - it('that is a function', function(done) { - col.insert({ name: name }, { safe: true }, function(err) { - assert.ifError(err); - var m = mquery({ name: name }).collection(col); - m.findOneAndRemove(function(err, res) { - assert.ifError(err); - assert.ok(res.value); - assert.equal(name, res.value.name); - done(); - }); - }); - }); - }); - describe('with 2 args', function() { - it('conditions + options', function() { - var m = mquery(col); - m.findOneAndRemove({ name: name }, { new: false }); - assert.deepEqual({ name: name }, m._conditions); - assert.deepEqual({ new: false }, m.options); - }); - it('query + options', function() { - var n = mquery({ name: name }); - var m = mquery(col); - m.findOneAndRemove(n, { sort: { x: 1 }}); - assert.deepEqual({ name: name }, m._conditions); - assert.deepEqual({ sort: { 'x': 1 }}, m.options); - }); - it('conditions + callback', function(done) { - col.insert({ name: name }, { safe: true }, function(err) { - assert.ifError(err); - var m = mquery(col); - m.findOneAndRemove({ name: name }, function(err, res) { - assert.ifError(err); - assert.equal(name, res.value.name); - done(); - }); - }); - }); - it('query + callback', function(done) { - col.insert({ name: name }, { safe: true }, function(err) { - assert.ifError(err); - var n = mquery({ name: name }); - var m = mquery(col); - m.findOneAndRemove(n, function(err, res) { - assert.ifError(err); - assert.equal(name, res.value.name); - done(); - }); - }); - }); - }); - describe('with 3 args', function() { - it('conditions + options + callback', function(done) { - name = 'findOneAndRemove + conds + options + cb'; - col.insert([{ name: name }, { name: 'a' }], { safe: true }, function(err) { - assert.ifError(err); - var m = mquery(col); - m.findOneAndRemove({ name: name }, { sort: { name: 1 }}, function(err, res) { - assert.ifError(err); - assert.ok(res.value); - assert.equal(name, res.value.name); - done(); - }); - }); - }); - }); - }); - - describe('exec', function() { - beforeEach(function(done) { - col.insert([{ name: 'exec', age: 1 }, { name: 'exec', age: 2 }], done); - }); - - afterEach(function(done) { - mquery(col).remove(done); - }); - - it('requires an op', function() { - assert.throws(function() { - mquery().exec(); - }, /Missing query type/); - }); - - describe('find', function() { - it('works', function(done) { - var m = mquery(col).find({ name: 'exec' }); - m.exec(function(err, docs) { - assert.ifError(err); - assert.equal(2, docs.length); - done(); - }); - }); - - it('works with readPreferences', function(done) { - var m = mquery(col).find({ name: 'exec' }); - try { - var rp = new require('mongodb').ReadPreference('primary'); - m.read(rp); - } catch (e) { - done(e.code === 'MODULE_NOT_FOUND' ? null : e); - return; - } - m.exec(function(err, docs) { - assert.ifError(err); - assert.equal(2, docs.length); - done(); - }); - }); - - it('works with hint', function(done) { - mquery(col).hint({ _id: 1 }).find({ name: 'exec' }).exec(function(err, docs) { - assert.ifError(err); - assert.equal(2, docs.length); - - mquery(col).hint('_id_').find({ age: 1 }).exec(function(err, docs) { - assert.ifError(err); - assert.equal(1, docs.length); - done(); - }); - }); - }); - - it('works with readConcern', function(done) { - var m = mquery(col).find({ name: 'exec' }); - m.readConcern('l'); - m.exec(function(err, docs) { - assert.ifError(err); - assert.equal(2, docs.length); - done(); - }); - }); - - it('works with collation', function(done) { - var m = mquery(col).find({ name: 'EXEC' }); - m.collation({ locale: 'en_US', strength: 1 }); - m.exec(function(err, docs) { - assert.ifError(err); - assert.equal(2, docs.length); - done(); - }); - }); - }); - - it('findOne', function(done) { - var m = mquery(col).findOne({ age: 2 }); - m.exec(function(err, doc) { - assert.ifError(err); - assert.equal(2, doc.age); - done(); - }); - }); - - it('count', function(done) { - var m = mquery(col).count({ name: 'exec' }); - m.exec(function(err, count) { - assert.ifError(err); - assert.equal(2, count); - done(); - }); - }); - - it('distinct', function(done) { - var m = mquery({ name: 'exec' }); - m.collection(col); - m.distinct('age'); - m.exec(function(err, array) { - assert.ifError(err); - assert.ok(Array.isArray(array)); - assert.equal(2, array.length); - assert(~array.indexOf(1)); - assert(~array.indexOf(2)); - done(); - }); - }); - - describe('update', function() { - var num; - - it('with a callback', function(done) { - var m = mquery(col); - m.where({ name: 'exec' }); - - m.count(function(err, _num) { - assert.ifError(err); - num = _num; - m.setOptions({ multi: true }); - m.update({ name: 'exec + update' }); - m.exec(function(err, res) { - assert.ifError(err); - assert.equal(num, res.result.n); - mquery(col).find({ name: 'exec + update' }, function(err, docs) { - assert.ifError(err); - assert.equal(num, docs.length); - done(); - }); - }); - }); - }); - - describe('updateMany', function() { - it('works', function(done) { - mquery(col).updateMany({ name: 'exec' }, { name: 'test' }). - exec(function(error) { - assert.ifError(error); - mquery(col).count({ name: 'test' }).exec(function(error, res) { - assert.ifError(error); - assert.equal(res, 2); - done(); - }); - }); - }); - it('works with write concern', function(done) { - mquery(col).updateMany({ name: 'exec' }, { name: 'test' }) - .w(1).j(true).wtimeout(1000) - .exec(function(error) { - assert.ifError(error); - mquery(col).count({ name: 'test' }).exec(function(error, res) { - assert.ifError(error); - assert.equal(res, 2); - done(); - }); - }); - }); - }); - - describe('updateOne', function() { - it('works', function(done) { - mquery(col).updateOne({ name: 'exec' }, { name: 'test' }). - exec(function(error) { - assert.ifError(error); - mquery(col).count({ name: 'test' }).exec(function(error, res) { - assert.ifError(error); - assert.equal(res, 1); - done(); - }); - }); - }); - }); - - describe('replaceOne', function() { - it('works', function(done) { - mquery(col).replaceOne({ name: 'exec' }, { name: 'test' }). - exec(function(error) { - assert.ifError(error); - mquery(col).findOne({ name: 'test' }).exec(function(error, res) { - assert.ifError(error); - assert.equal(res.name, 'test'); - assert.ok(res.age == null); - done(); - }); - }); - }); - }); - - it('without a callback', function(done) { - var m = mquery(col); - m.where({ name: 'exec + update' }).setOptions({ multi: true }); - m.update({ name: 'exec' }); - - // unsafe write - m.exec(); - - setTimeout(function() { - mquery(col).find({ name: 'exec' }, function(err, docs) { - assert.ifError(err); - assert.equal(2, docs.length); - done(); - }); - }, 200); - }); - it('preserves key ordering', function(done) { - var m = mquery(col); - - var m2 = m.update({ _id : 'something' }, { '1' : 1, '2' : 2, '3' : 3}); - var doc = m2._updateForExec().$set; - var count = 0; - for (var i in doc) { - if (count == 0) { - assert.equal('1', i); - } else if (count == 1) { - assert.equal('2', i); - } else if (count == 2) { - assert.equal('3', i); - } - count++; - } - done(); - }); - }); - - describe('remove', function() { - it('with a callback', function(done) { - var m = mquery(col).where({ age: 2 }).remove(); - m.exec(function(err, res) { - assert.ifError(err); - assert.equal(1, res.result.n); - done(); - }); - }); - - it('without a callback', function(done) { - var m = mquery(col).where({ age: 1 }).remove(); - m.exec(); - - setTimeout(function() { - mquery(col).where('name', 'exec').count(function(err, num) { - assert.equal(1, num); - done(); - }); - }, 200); - }); - }); - - describe('deleteOne', function() { - it('with a callback', function(done) { - var m = mquery(col).where({ age: { $gte: 0 } }).deleteOne(); - m.exec(function(err, res) { - assert.ifError(err); - assert.equal(res.result.n, 1); - done(); - }); - }); - - it('with justOne set', function(done) { - var m = mquery(col).where({ age: { $gte: 0 } }). - // Should ignore `justOne` - setOptions({ justOne: false }). - deleteOne(); - m.exec(function(err, res) { - assert.ifError(err); - assert.equal(res.result.n, 1); - done(); - }); - }); - }); - - describe('deleteMany', function() { - it('with a callback', function(done) { - var m = mquery(col).where({ age: { $gte: 0 } }).deleteMany(); - m.exec(function(err, res) { - assert.ifError(err); - assert.equal(res.result.n, 2); - done(); - }); - }); - }); - - describe('findOneAndUpdate', function() { - it('with a callback', function(done) { - var m = mquery(col); - m.findOneAndUpdate({ name: 'exec', age: 1 }, { $set: { name: 'findOneAndUpdate' }}); - m.exec(function(err, res) { - assert.ifError(err); - assert.equal('findOneAndUpdate', res.value.name); - done(); - }); - }); - }); - - describe('findOneAndRemove', function() { - it('with a callback', function(done) { - var m = mquery(col); - m.findOneAndRemove({ name: 'exec', age: 2 }); - m.exec(function(err, res) { - assert.ifError(err); - assert.equal('exec', res.value.name); - assert.equal(2, res.value.age); - mquery(col).count({ name: 'exec' }, function(err, num) { - assert.ifError(err); - assert.equal(1, num); - done(); - }); - }); - }); - }); - }); - - describe('setTraceFunction', function() { - beforeEach(function(done) { - col.insert([{ name: 'trace', age: 93 }], done); - }); - - it('calls trace function when executing query', function(done) { - var m = mquery(col); - - var resultTraceCalled; - - m.setTraceFunction(function(method, queryInfo) { - try { - assert.equal('findOne', method); - assert.equal('trace', queryInfo.conditions.name); - } catch (e) { - done(e); - } - - return function(err, result, millis) { - try { - assert.equal(93, result.age); - assert.ok(typeof millis === 'number'); - } catch (e) { - done(e); - } - resultTraceCalled = true; - }; - }); - - m.findOne({name: 'trace'}, function(err, doc) { - assert.ifError(err); - assert.equal(resultTraceCalled, true); - assert.equal(93, doc.age); - done(); - }); - }); - - it('inherits trace function when calling toConstructor', function(done) { - function traceFunction() { return function() {}; } - - var tracedQuery = mquery().setTraceFunction(traceFunction).toConstructor(); - - var query = tracedQuery(); - assert.equal(traceFunction, query._traceFunction); - - done(); - }); - }); - - describe('thunk', function() { - it('returns a function', function(done) { - assert.equal('function', typeof mquery().thunk()); - done(); - }); - - it('passes the fn arg to `exec`', function(done) { - function cb() {} - var m = mquery(); - - m.exec = function testing(fn) { - assert.equal(this, m); - assert.equal(cb, fn); - done(); - }; - - m.thunk()(cb); - }); - }); - - describe('then', function() { - before(function(done) { - col.insert([{ name: 'then', age: 1 }, { name: 'then', age: 2 }], done); - }); - - after(function(done) { - mquery(col).remove({ name: 'then' }).exec(done); - }); - - it('returns a promise A+ compat object', function(done) { - var m = mquery(col).find(); - assert.equal('function', typeof m.then); - done(); - }); - - it('creates a promise that is resolved on success', function(done) { - var promise = mquery(col).count({ name: 'then' }).then(); - promise.then(function(count) { - assert.equal(2, count); - done(); - }, done); - }); - - it('supports exec() cb being called synchronously #66', function(done) { - var query = mquery(col).count({ name: 'then' }); - query.exec = function(cb) { - cb(null, 66); - }; - - query.then(success, done); - function success(count) { - assert.equal(66, count); - done(); - } - }); - - it('supports other Promise libs', function(done) { - var bluebird = mquery.Promise; - - // hack for testing - mquery.Promise = function P() { - mquery.Promise = bluebird; - this.then = function(x, y) { - return x + y; - }; - }; - - var val = mquery(col).count({ name: 'exec' }).then(1, 2); - assert.equal(val, 3); - done(); - }); - }); - - describe('stream', function() { - before(function(done) { - col.insert([{ name: 'stream', age: 1 }, { name: 'stream', age: 2 }], done); - }); - - after(function(done) { - mquery(col).remove({ name: 'stream' }).exec(done); - }); - - describe('throws', function() { - describe('if used with non-find operations', function() { - var ops = ['update', 'findOneAndUpdate', 'remove', 'count', 'distinct']; - - ops.forEach(function(op) { - assert.throws(function() { - mquery(col)[op]().stream(); - }); - }); - }); - }); - - it('returns a stream', function(done) { - var stream = mquery(col).find({ name: 'stream' }).stream(); - var count = 0; - var err; - - stream.on('data', function(doc) { - assert.equal('stream', doc.name); - ++count; - }); - - stream.on('error', function(er) { - err = er; - }); - - stream.on('end', function() { - if (err) return done(err); - assert.equal(2, count); - done(); - }); - }); - }); - - function noDistinct(type) { - it('cannot be used with distinct()', function(done) { - assert.throws(function() { - mquery().distinct('name')[type](4); - }, new RegExp(type + ' cannot be used with distinct')); - done(); - }); - } - - function no(method, type) { - it('cannot be used with ' + method + '()', function(done) { - assert.throws(function() { - mquery()[method]()[type](4); - }, new RegExp(type + ' cannot be used with ' + method)); - done(); - }); - } - - // query internal - - describe('_updateForExec', function() { - it('returns a clone of the update object with same key order #19', function(done) { - var update = {}; - update.$push = { n: { $each: [{x:10}], $slice: -1, $sort: {x:1}}}; - - var q = mquery().update({ x: 1 }, update); - - // capture original key order - var order = []; - var key; - for (key in q._update.$push.n) { - order.push(key); - } - - // compare output - var doc = q._updateForExec(); - var i = 0; - for (key in doc.$push.n) { - assert.equal(key, order[i]); - i++; - } - - done(); - }); - }); -}); diff --git a/node_modules/mquery/test/utils.test.js b/node_modules/mquery/test/utils.test.js deleted file mode 100644 index ff95f33..0000000 --- a/node_modules/mquery/test/utils.test.js +++ /dev/null @@ -1,144 +0,0 @@ -'use strict'; - -var Buffer = require('safe-buffer').Buffer; -var utils = require('../lib/utils'); -var assert = require('assert'); -var debug = require('debug'); - -var mongo; -try { - mongo = new require('mongodb'); -} catch (e) { - debug('mongo', 'cannot construct mongodb instance'); -} - -describe('lib/utils', function() { - describe('clone', function() { - it('clones constructors named ObjectId', function(done) { - function ObjectId(id) { - this.id = id; - } - - var o1 = new ObjectId('1234'); - var o2 = utils.clone(o1); - assert.ok(o2 instanceof ObjectId); - - done(); - }); - - it('clones constructors named ObjectID', function(done) { - function ObjectID(id) { - this.id = id; - } - - var o1 = new ObjectID('1234'); - var o2 = utils.clone(o1); - - assert.ok(o2 instanceof ObjectID); - done(); - }); - - it('does not clone constructors named ObjectIdd', function(done) { - function ObjectIdd(id) { - this.id = id; - } - - var o1 = new ObjectIdd('1234'); - var o2 = utils.clone(o1); - assert.ok(!(o2 instanceof ObjectIdd)); - - done(); - }); - - it('optionally clones ObjectId constructors using its clone method', function(done) { - function ObjectID(id) { - this.id = id; - this.cloned = false; - } - - ObjectID.prototype.clone = function() { - var ret = new ObjectID(this.id); - ret.cloned = true; - return ret; - }; - - var id = 1234; - var o1 = new ObjectID(id); - assert.equal(id, o1.id); - assert.equal(false, o1.cloned); - - var o2 = utils.clone(o1); - assert.ok(o2 instanceof ObjectID); - assert.equal(id, o2.id); - assert.ok(o2.cloned); - done(); - }); - - it('clones mongodb.ReadPreferences', function(done) { - if (!mongo) return done(); - - var tags = [ - {dc: 'tag1'} - ]; - var prefs = [ - new mongo.ReadPreference('primary'), - new mongo.ReadPreference(mongo.ReadPreference.PRIMARY_PREFERRED), - new mongo.ReadPreference('secondary', tags) - ]; - - var prefsCloned = utils.clone(prefs); - - for (var i = 0; i < prefsCloned.length; i++) { - assert.notEqual(prefs[i], prefsCloned[i]); - if (prefs[i].tags) { - assert.ok(prefsCloned[i].tags); - assert.notEqual(prefs[i].tags, prefsCloned[i].tags); - assert.notEqual(prefs[i].tags[0], prefsCloned[i].tags[0]); - } else { - assert.equal(prefsCloned[i].tags, null); - } - } - - done(); - }); - - it('clones mongodb.Binary', function(done) { - if (!mongo) return done(); - var buf = Buffer.from('hi'); - var binary = new mongo.Binary(buf, 2); - var clone = utils.clone(binary); - assert.equal(binary.sub_type, clone.sub_type); - assert.equal(String(binary.buffer), String(buf)); - assert.ok(binary !== clone); - done(); - }); - - it('handles objects with no constructor', function(done) { - var name = '335'; - - var o = Object.create(null); - o.name = name; - - var clone; - assert.doesNotThrow(function() { - clone = utils.clone(o); - }); - - assert.equal(name, clone.name); - assert.ok(o != clone); - done(); - }); - - it('handles buffers', function(done) { - var buff = Buffer.alloc(10); - buff.fill(1); - var clone = utils.clone(buff); - - for (var i = 0; i < buff.length; i++) { - assert.equal(buff[i], clone[i]); - } - - done(); - }); - }); -}); -- cgit v1.2.3