mongoose 6.3.3 → 6.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +1 -1
- package/dist/browser.umd.js +1 -1
- package/lgtm.yml +12 -0
- package/lib/cast/objectid.js +3 -2
- package/lib/connection.js +3 -2
- package/lib/document.js +15 -8
- package/lib/error/index.js +2 -2
- package/lib/helpers/clone.js +9 -2
- package/lib/helpers/common.js +3 -4
- package/lib/helpers/discriminator/areDiscriminatorValuesEqual.js +2 -2
- package/lib/helpers/isBsonType.js +5 -3
- package/lib/helpers/path/setDottedPath.js +14 -1
- package/lib/helpers/topology/isAtlas.js +15 -2
- package/lib/helpers/update/applyTimestampsToChildren.js +4 -0
- package/lib/index.js +4 -3
- package/lib/model.js +38 -54
- package/lib/query.js +4 -1
- package/lib/queryhelpers.js +3 -2
- package/lib/schema/decimal128.js +4 -4
- package/lib/schema/map.js +8 -0
- package/lib/schema/objectid.js +4 -3
- package/lib/schema/string.js +2 -2
- package/lib/schema.js +41 -2
- package/lib/types/DocumentArray/methods/index.js +3 -3
- package/lib/types/array/methods/index.js +3 -3
- package/lib/types/map.js +4 -4
- package/lib/utils.js +3 -4
- package/package.json +18 -16
- package/types/aggregate.d.ts +3 -4
- package/types/callback.d.ts +8 -0
- package/types/collection.d.ts +46 -0
- package/types/connection.d.ts +92 -72
- package/types/document.d.ts +1 -1
- package/types/error.d.ts +5 -1
- package/types/helpers.d.ts +33 -0
- package/types/index.d.ts +32 -1859
- package/types/indizes.d.ts +98 -0
- package/types/middlewares.d.ts +14 -0
- package/types/models.d.ts +419 -0
- package/types/populate.d.ts +40 -0
- package/types/query.d.ts +637 -0
- package/types/schematypes.d.ts +418 -0
- package/types/session.d.ts +36 -0
- package/types/types.d.ts +102 -0
- package/types/utility.d.ts +13 -0
- package/types/validation.d.ts +32 -0
- package/.lgtm.yml +0 -3
package/lgtm.yml
ADDED
package/lib/cast/objectid.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const isBsonType = require('../helpers/isBsonType');
|
|
3
4
|
const ObjectId = require('../driver').get().ObjectId;
|
|
4
5
|
|
|
5
6
|
module.exports = function castObjectId(value) {
|
|
@@ -7,12 +8,12 @@ module.exports = function castObjectId(value) {
|
|
|
7
8
|
return value;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
if (value
|
|
11
|
+
if (isBsonType(value, 'ObjectID')) {
|
|
11
12
|
return value;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
if (value._id) {
|
|
15
|
-
if (value._id
|
|
16
|
+
if (isBsonType(value._id, 'ObjectID')) {
|
|
16
17
|
return value._id;
|
|
17
18
|
}
|
|
18
19
|
if (value._id.toString instanceof Function) {
|
package/lib/connection.js
CHANGED
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
const ChangeStream = require('./cursor/ChangeStream');
|
|
8
8
|
const EventEmitter = require('events').EventEmitter;
|
|
9
9
|
const Schema = require('./schema');
|
|
10
|
-
const Collection = require('./driver').get().Collection;
|
|
11
10
|
const STATES = require('./connectionstate');
|
|
12
11
|
const MongooseError = require('./error/index');
|
|
13
12
|
const SyncIndexesError = require('./error/syncIndexes');
|
|
14
13
|
const PromiseProvider = require('./promise_provider');
|
|
15
14
|
const ServerSelectionError = require('./error/serverSelection');
|
|
16
15
|
const applyPlugins = require('./helpers/schema/applyPlugins');
|
|
16
|
+
const driver = require('./driver');
|
|
17
17
|
const promiseOrCallback = require('./helpers/promiseOrCallback');
|
|
18
18
|
const get = require('./helpers/get');
|
|
19
19
|
const immediate = require('./helpers/immediate');
|
|
@@ -548,7 +548,7 @@ Connection.prototype.dropDatabase = _wrapConnHelper(function dropDatabase(cb) {
|
|
|
548
548
|
// If `dropDatabase()` is called, this model's collection will not be
|
|
549
549
|
// init-ed. It is sufficiently common to call `dropDatabase()` after
|
|
550
550
|
// `mongoose.connect()` but before creating models that we want to
|
|
551
|
-
// support this. See gh-
|
|
551
|
+
// support this. See gh-6796
|
|
552
552
|
for (const name of Object.keys(this.models)) {
|
|
553
553
|
delete this.models[name].$init;
|
|
554
554
|
}
|
|
@@ -1026,6 +1026,7 @@ Connection.prototype.collection = function(name, options) {
|
|
|
1026
1026
|
};
|
|
1027
1027
|
options = Object.assign({}, defaultOptions, options ? utils.clone(options) : {});
|
|
1028
1028
|
options.$wasForceClosed = this.$wasForceClosed;
|
|
1029
|
+
const Collection = driver.get().Collection;
|
|
1029
1030
|
if (!(name in this.collections)) {
|
|
1030
1031
|
this.collections[name] = new Collection(name, this, options);
|
|
1031
1032
|
}
|
package/lib/document.js
CHANGED
|
@@ -1323,6 +1323,10 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1323
1323
|
|
|
1324
1324
|
if (!schema) {
|
|
1325
1325
|
this.$__set(pathToMark, path, options, constructing, parts, schema, val, priorVal);
|
|
1326
|
+
|
|
1327
|
+
if (pathType === 'nested' && val == null) {
|
|
1328
|
+
cleanModifiedSubpaths(this, path);
|
|
1329
|
+
}
|
|
1326
1330
|
return this;
|
|
1327
1331
|
}
|
|
1328
1332
|
|
|
@@ -1374,7 +1378,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1374
1378
|
})();
|
|
1375
1379
|
|
|
1376
1380
|
let didPopulate = false;
|
|
1377
|
-
if (refMatches && val instanceof Document) {
|
|
1381
|
+
if (refMatches && val instanceof Document && (!val.$__.wasPopulated || utils.deepEqual(val.$__.wasPopulated.value, val._id))) {
|
|
1378
1382
|
const unpopulatedValue = (schema && schema.$isSingleNested) ? schema.cast(val, this) : val._id;
|
|
1379
1383
|
this.$populated(path, unpopulatedValue, { [populateModelSymbol]: val.constructor });
|
|
1380
1384
|
val.$__.wasPopulated = { value: unpopulatedValue };
|
|
@@ -3460,9 +3464,9 @@ Document.prototype.$toObject = function(options, json) {
|
|
|
3460
3464
|
|
|
3461
3465
|
const path = json ? 'toJSON' : 'toObject';
|
|
3462
3466
|
const baseOptions = this.constructor &&
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3467
|
+
this.constructor.base &&
|
|
3468
|
+
this.constructor.base.options &&
|
|
3469
|
+
get(this.constructor.base.options, path) || {};
|
|
3466
3470
|
const schemaOptions = this.$__schema && this.$__schema.options || {};
|
|
3467
3471
|
// merge base default options with Schema's set default options if available.
|
|
3468
3472
|
// `clone` is necessary here because `utils.options` directly modifies the second input.
|
|
@@ -3470,8 +3474,8 @@ Document.prototype.$toObject = function(options, json) {
|
|
|
3470
3474
|
defaultOptions = utils.options(defaultOptions, clone(schemaOptions[path] || {}));
|
|
3471
3475
|
|
|
3472
3476
|
// If options do not exist or is not an object, set it to empty object
|
|
3473
|
-
options = utils.isPOJO(options) ?
|
|
3474
|
-
options._calledWithOptions = options._calledWithOptions ||
|
|
3477
|
+
options = utils.isPOJO(options) ? { ...options } : {};
|
|
3478
|
+
options._calledWithOptions = options._calledWithOptions || { ...options };
|
|
3475
3479
|
|
|
3476
3480
|
let _minimize;
|
|
3477
3481
|
if (options._calledWithOptions.minimize != null) {
|
|
@@ -3495,11 +3499,12 @@ Document.prototype.$toObject = function(options, json) {
|
|
|
3495
3499
|
// `clone()` will recursively call `$toObject()` on embedded docs, so we
|
|
3496
3500
|
// need the original options the user passed in, plus `_isNested` and
|
|
3497
3501
|
// `_parentOptions` for checking whether we need to depopulate.
|
|
3498
|
-
const cloneOptions = Object.assign(
|
|
3502
|
+
const cloneOptions = Object.assign({}, options, {
|
|
3499
3503
|
_isNested: true,
|
|
3500
3504
|
json: json,
|
|
3501
3505
|
minimize: _minimize,
|
|
3502
|
-
flattenMaps: flattenMaps
|
|
3506
|
+
flattenMaps: flattenMaps,
|
|
3507
|
+
_seen: (options && options._seen) || new Map()
|
|
3503
3508
|
});
|
|
3504
3509
|
|
|
3505
3510
|
if (utils.hasUserDefinedProperty(options, 'getters')) {
|
|
@@ -4222,8 +4227,10 @@ Document.prototype.populate = function populate() {
|
|
|
4222
4227
|
* @api public
|
|
4223
4228
|
* @return {Array<Document>} array of populated documents. Empty array if there are no populated documents associated with this document.
|
|
4224
4229
|
* @memberOf Document
|
|
4230
|
+
* @method $getPopulatedDocs
|
|
4225
4231
|
* @instance
|
|
4226
4232
|
*/
|
|
4233
|
+
|
|
4227
4234
|
Document.prototype.$getPopulatedDocs = function $getPopulatedDocs() {
|
|
4228
4235
|
let keys = [];
|
|
4229
4236
|
if (this.$__.populated != null) {
|
package/lib/error/index.js
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
* Mongoose-specific errors.
|
|
6
6
|
*
|
|
7
7
|
* #### Example:
|
|
8
|
-
* const Model = mongoose.model('Test', new Schema({ answer: Number }));
|
|
8
|
+
* const Model = mongoose.model('Test', new mongoose.Schema({ answer: Number }));
|
|
9
9
|
* const doc = new Model({ answer: 'not a number' });
|
|
10
10
|
* const err = doc.validateSync();
|
|
11
11
|
*
|
|
12
|
-
* err instanceof mongoose.Error; // true
|
|
12
|
+
* err instanceof mongoose.Error.ValidationError; // true
|
|
13
13
|
*
|
|
14
14
|
* @constructor Error
|
|
15
15
|
* @param {String} msg Error message
|
package/lib/helpers/clone.js
CHANGED
|
@@ -77,7 +77,7 @@ function clone(obj, options, isArrayChild) {
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
if (obj
|
|
80
|
+
if (isBsonType(obj, 'ObjectID')) {
|
|
81
81
|
return new ObjectId(obj.id);
|
|
82
82
|
}
|
|
83
83
|
|
|
@@ -118,9 +118,16 @@ module.exports = clone;
|
|
|
118
118
|
|
|
119
119
|
function cloneObject(obj, options, isArrayChild) {
|
|
120
120
|
const minimize = options && options.minimize;
|
|
121
|
+
const omitUndefined = options && options.omitUndefined;
|
|
122
|
+
const seen = options && options._seen;
|
|
121
123
|
const ret = {};
|
|
122
124
|
let hasKeys;
|
|
123
125
|
|
|
126
|
+
if (seen && seen.has(obj)) {
|
|
127
|
+
return seen.get(obj);
|
|
128
|
+
} else if (seen) {
|
|
129
|
+
seen.set(obj, ret);
|
|
130
|
+
}
|
|
124
131
|
if (trustedSymbol in obj) {
|
|
125
132
|
ret[trustedSymbol] = obj[trustedSymbol];
|
|
126
133
|
}
|
|
@@ -138,7 +145,7 @@ function cloneObject(obj, options, isArrayChild) {
|
|
|
138
145
|
// Don't pass `isArrayChild` down
|
|
139
146
|
const val = clone(obj[key], options, false);
|
|
140
147
|
|
|
141
|
-
if (minimize === false && typeof val === 'undefined') {
|
|
148
|
+
if ((minimize === false || omitUndefined) && typeof val === 'undefined') {
|
|
142
149
|
delete ret[key];
|
|
143
150
|
} else if (minimize !== true || (typeof val !== 'undefined')) {
|
|
144
151
|
hasKeys || (hasKeys = true);
|
package/lib/helpers/common.js
CHANGED
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
const Binary = require('../driver').get().Binary;
|
|
8
|
-
const
|
|
9
|
-
const ObjectId = require('../types/objectid');
|
|
8
|
+
const isBsonType = require('./isBsonType');
|
|
10
9
|
const isMongooseObject = require('./isMongooseObject');
|
|
11
10
|
|
|
12
11
|
exports.flatten = flatten;
|
|
@@ -99,9 +98,9 @@ function shouldFlatten(val) {
|
|
|
99
98
|
return val &&
|
|
100
99
|
typeof val === 'object' &&
|
|
101
100
|
!(val instanceof Date) &&
|
|
102
|
-
!(val
|
|
101
|
+
!isBsonType(val, 'ObjectID') &&
|
|
103
102
|
(!Array.isArray(val) || val.length !== 0) &&
|
|
104
103
|
!(val instanceof Buffer) &&
|
|
105
|
-
!(val
|
|
104
|
+
!isBsonType(val, 'Decimal128') &&
|
|
106
105
|
!(val instanceof Binary);
|
|
107
106
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const isBsonType = require('../isBsonType');
|
|
4
4
|
|
|
5
5
|
module.exports = function areDiscriminatorValuesEqual(a, b) {
|
|
6
6
|
if (typeof a === 'string' && typeof b === 'string') {
|
|
@@ -9,7 +9,7 @@ module.exports = function areDiscriminatorValuesEqual(a, b) {
|
|
|
9
9
|
if (typeof a === 'number' && typeof b === 'number') {
|
|
10
10
|
return a === b;
|
|
11
11
|
}
|
|
12
|
-
if (a
|
|
12
|
+
if (isBsonType(a, 'ObjectID') && isBsonType(b, 'ObjectID')) {
|
|
13
13
|
return a.toString() === b.toString();
|
|
14
14
|
}
|
|
15
15
|
return false;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const get = require('./get');
|
|
4
|
-
|
|
5
3
|
/*!
|
|
6
4
|
* Get the bson type, if it exists
|
|
7
5
|
*/
|
|
8
6
|
|
|
9
7
|
function isBsonType(obj, typename) {
|
|
10
|
-
return
|
|
8
|
+
return (
|
|
9
|
+
typeof obj === 'object' &&
|
|
10
|
+
obj !== null &&
|
|
11
|
+
obj._bsontype === typename
|
|
12
|
+
);
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
module.exports = isBsonType;
|
|
@@ -1,14 +1,25 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const specialProperties = require('../specialProperties');
|
|
4
|
+
|
|
5
|
+
|
|
3
6
|
module.exports = function setDottedPath(obj, path, val) {
|
|
4
7
|
if (path.indexOf('.') === -1) {
|
|
8
|
+
if (specialProperties.has(path)) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
|
|
5
12
|
obj[path] = val;
|
|
6
13
|
return;
|
|
7
14
|
}
|
|
8
15
|
const parts = path.split('.');
|
|
16
|
+
|
|
9
17
|
const last = parts.pop();
|
|
10
18
|
let cur = obj;
|
|
11
19
|
for (const part of parts) {
|
|
20
|
+
if (specialProperties.has(part)) {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
12
23
|
if (cur[part] == null) {
|
|
13
24
|
cur[part] = {};
|
|
14
25
|
}
|
|
@@ -16,5 +27,7 @@ module.exports = function setDottedPath(obj, path, val) {
|
|
|
16
27
|
cur = cur[part];
|
|
17
28
|
}
|
|
18
29
|
|
|
19
|
-
|
|
30
|
+
if (!specialProperties.has(last)) {
|
|
31
|
+
cur[last] = val;
|
|
32
|
+
}
|
|
20
33
|
};
|
|
@@ -8,6 +8,19 @@ module.exports = function isAtlas(topologyDescription) {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
const hostnames = Array.from(topologyDescription.servers.keys());
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
|
|
12
|
+
if (hostnames.length === 0) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
for (let i = 0, il = hostnames.length; i < il; ++i) {
|
|
17
|
+
const url = new URL(hostnames[i]);
|
|
18
|
+
if (
|
|
19
|
+
url.hostname.endsWith('.mongodb.net') === false ||
|
|
20
|
+
url.port !== '27017'
|
|
21
|
+
) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return true;
|
|
13
26
|
};
|
|
@@ -61,6 +61,8 @@ function applyTimestampsToChildren(now, update, schema) {
|
|
|
61
61
|
if (createdAt != null) {
|
|
62
62
|
subdoc[createdAt] = now;
|
|
63
63
|
}
|
|
64
|
+
|
|
65
|
+
applyTimestampsToChildren(now, subdoc, $path.schema);
|
|
64
66
|
});
|
|
65
67
|
} else {
|
|
66
68
|
if (updatedAt != null) {
|
|
@@ -69,6 +71,8 @@ function applyTimestampsToChildren(now, update, schema) {
|
|
|
69
71
|
if (createdAt != null) {
|
|
70
72
|
op[key][createdAt] = now;
|
|
71
73
|
}
|
|
74
|
+
|
|
75
|
+
applyTimestampsToChildren(now, op[key], $path.schema);
|
|
72
76
|
}
|
|
73
77
|
}
|
|
74
78
|
}
|
package/lib/index.js
CHANGED
|
@@ -34,6 +34,7 @@ const PromiseProvider = require('./promise_provider');
|
|
|
34
34
|
const shardingPlugin = require('./plugins/sharding');
|
|
35
35
|
const trusted = require('./helpers/query/trusted').trusted;
|
|
36
36
|
const sanitizeFilter = require('./helpers/query/sanitizeFilter');
|
|
37
|
+
const isBsonType = require('./helpers/isBsonType');
|
|
37
38
|
|
|
38
39
|
const defaultMongooseSymbol = Symbol.for('mongoose:default');
|
|
39
40
|
|
|
@@ -153,7 +154,7 @@ Mongoose.prototype.driver = driver;
|
|
|
153
154
|
* mongoose.set('debug', function(collectionName, methodName, ...methodArgs) {}); // use custom function to log collection methods + arguments
|
|
154
155
|
*
|
|
155
156
|
* Currently supported options are:
|
|
156
|
-
* - 'debug': If `true`, prints the operations mongoose sends to MongoDB to the console. If a writable stream is passed, it will log to that stream, without colorization. If a callback function is passed, it will receive the collection name, the method name, then all
|
|
157
|
+
* - 'debug': If `true`, prints the operations mongoose sends to MongoDB to the console. If a writable stream is passed, it will log to that stream, without colorization. If a callback function is passed, it will receive the collection name, the method name, then all arguments passed to the method. For example, if you wanted to replicate the default logging, you could output from the callback `Mongoose: ${collectionName}.${methodName}(${methodArgs.join(', ')})`.
|
|
157
158
|
* - 'returnOriginal': If `false`, changes the default `returnOriginal` option to `findOneAndUpdate()`, `findByIdAndUpdate`, and `findOneAndReplace()` to false. This is equivalent to setting the `new` option to `true` for `findOneAndX()` calls by default. Read our [`findOneAndUpdate()` tutorial](/docs/tutorials/findoneandupdate.html) for more information.
|
|
158
159
|
* - 'bufferCommands': enable/disable mongoose's buffering mechanism for all connections and models
|
|
159
160
|
* - 'cloneSchemas': false by default. Set to `true` to `clone()` all schemas before compiling into a model.
|
|
@@ -274,6 +275,7 @@ Mongoose.prototype.get = Mongoose.prototype.set;
|
|
|
274
275
|
Mongoose.prototype.createConnection = function(uri, options, callback) {
|
|
275
276
|
const _mongoose = this instanceof Mongoose ? this : mongoose;
|
|
276
277
|
|
|
278
|
+
const Connection = driver.get().getConnection();
|
|
277
279
|
const conn = new Connection(_mongoose);
|
|
278
280
|
if (typeof options === 'function') {
|
|
279
281
|
callback = options;
|
|
@@ -995,8 +997,7 @@ Mongoose.prototype.isValidObjectId = function(v) {
|
|
|
995
997
|
*/
|
|
996
998
|
|
|
997
999
|
Mongoose.prototype.isObjectIdOrHexString = function(v) {
|
|
998
|
-
|
|
999
|
-
return v instanceof _mongoose.Types.ObjectId || (typeof v === 'string' && objectIdHexRegexp.test(v));
|
|
1000
|
+
return isBsonType(v, 'ObjectID') || (typeof v === 'string' && objectIdHexRegexp.test(v));
|
|
1000
1001
|
};
|
|
1001
1002
|
|
|
1002
1003
|
/**
|
package/lib/model.js
CHANGED
|
@@ -768,6 +768,7 @@ Model.prototype.$__delta = function() {
|
|
|
768
768
|
transform: false,
|
|
769
769
|
virtuals: false,
|
|
770
770
|
getters: false,
|
|
771
|
+
omitUndefined: true,
|
|
771
772
|
_isNested: true
|
|
772
773
|
});
|
|
773
774
|
operand(this, where, delta, data, value);
|
|
@@ -1488,61 +1489,68 @@ Model.syncIndexes = function syncIndexes(options, callback) {
|
|
|
1488
1489
|
* the result of this function would be the result of
|
|
1489
1490
|
* Model.syncIndexes().
|
|
1490
1491
|
*
|
|
1491
|
-
* @param {Object} options
|
|
1492
|
+
* @param {Object} [options]
|
|
1492
1493
|
* @param {Function} callback optional callback
|
|
1493
|
-
* @returns {Promise} which
|
|
1494
|
-
* are indexes that would be dropped in
|
|
1494
|
+
* @returns {Promise} which contains an object, {toDrop, toCreate}, which
|
|
1495
|
+
* are indexes that would be dropped in MongoDB and indexes that would be created in MongoDB.
|
|
1495
1496
|
*/
|
|
1496
1497
|
|
|
1497
1498
|
Model.diffIndexes = function diffIndexes(options, callback) {
|
|
1499
|
+
if (typeof options === 'function') {
|
|
1500
|
+
callback = options;
|
|
1501
|
+
options = null;
|
|
1502
|
+
}
|
|
1498
1503
|
const toDrop = [];
|
|
1499
1504
|
const toCreate = [];
|
|
1500
1505
|
callback = this.$handleCallbackError(callback);
|
|
1501
1506
|
return this.db.base._promiseOrCallback(callback, cb => {
|
|
1502
1507
|
cb = this.$wrapCallback(cb);
|
|
1503
|
-
this.listIndexes((err,
|
|
1504
|
-
if (
|
|
1505
|
-
|
|
1508
|
+
this.listIndexes((err, dbIndexes) => {
|
|
1509
|
+
if (dbIndexes === undefined) {
|
|
1510
|
+
dbIndexes = [];
|
|
1506
1511
|
}
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
for (const
|
|
1512
|
+
dbIndexes = getRelatedDBIndexes(this, dbIndexes);
|
|
1513
|
+
const schemaIndexes = getRelatedSchemaIndexes(this, this.schema.indexes());
|
|
1514
|
+
|
|
1515
|
+
for (const dbIndex of dbIndexes) {
|
|
1511
1516
|
let found = false;
|
|
1512
1517
|
// Never try to drop `_id` index, MongoDB server doesn't allow it
|
|
1513
|
-
if (isDefaultIdIndex(
|
|
1518
|
+
if (isDefaultIdIndex(dbIndex)) {
|
|
1514
1519
|
continue;
|
|
1515
1520
|
}
|
|
1516
1521
|
|
|
1517
|
-
for (const
|
|
1518
|
-
const
|
|
1519
|
-
|
|
1520
|
-
|
|
1522
|
+
for (const [schemaIndexKeysObject, schemaIndexOptions] of schemaIndexes) {
|
|
1523
|
+
const options = decorateDiscriminatorIndexOptions(this.schema, utils.clone(schemaIndexOptions));
|
|
1524
|
+
applySchemaCollation(schemaIndexKeysObject, options, this.schema.options);
|
|
1525
|
+
|
|
1526
|
+
if (isIndexEqual(schemaIndexKeysObject, options, dbIndex)) {
|
|
1521
1527
|
found = true;
|
|
1522
1528
|
}
|
|
1523
1529
|
}
|
|
1524
1530
|
|
|
1525
1531
|
if (!found) {
|
|
1526
|
-
toDrop.push(
|
|
1532
|
+
toDrop.push(dbIndex.name);
|
|
1527
1533
|
}
|
|
1528
1534
|
}
|
|
1529
1535
|
// Iterate through the indexes created on the schema and
|
|
1530
1536
|
// compare against the indexes in mongodb.
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1537
|
+
if (!options || options.toCreate !== false) {
|
|
1538
|
+
for (const schemaIndex of schemaIndexes) {
|
|
1539
|
+
let found = false;
|
|
1540
|
+
const key = schemaIndex[0];
|
|
1541
|
+
const options = decorateDiscriminatorIndexOptions(this.schema, utils.clone(schemaIndex[1]));
|
|
1542
|
+
for (const index of dbIndexes) {
|
|
1543
|
+
if (isDefaultIdIndex(index)) {
|
|
1544
|
+
continue;
|
|
1545
|
+
}
|
|
1546
|
+
if (isIndexEqual(key, options, index)) {
|
|
1547
|
+
found = true;
|
|
1548
|
+
}
|
|
1538
1549
|
}
|
|
1539
|
-
if (
|
|
1540
|
-
|
|
1550
|
+
if (!found) {
|
|
1551
|
+
toCreate.push(key);
|
|
1541
1552
|
}
|
|
1542
1553
|
}
|
|
1543
|
-
if (!found) {
|
|
1544
|
-
toCreate.push(key);
|
|
1545
|
-
}
|
|
1546
1554
|
}
|
|
1547
1555
|
cb(null, { toDrop, toCreate });
|
|
1548
1556
|
});
|
|
@@ -1568,36 +1576,12 @@ Model.cleanIndexes = function cleanIndexes(callback) {
|
|
|
1568
1576
|
return this.db.base._promiseOrCallback(callback, cb => {
|
|
1569
1577
|
const collection = this.$__collection;
|
|
1570
1578
|
|
|
1571
|
-
this.
|
|
1579
|
+
this.diffIndexes({ toCreate: false }, (err, res) => {
|
|
1572
1580
|
if (err != null) {
|
|
1573
1581
|
return cb(err);
|
|
1574
1582
|
}
|
|
1575
1583
|
|
|
1576
|
-
|
|
1577
|
-
const schemaIndexes = getRelatedSchemaIndexes(this, this.schema.indexes());
|
|
1578
|
-
|
|
1579
|
-
const toDrop = [];
|
|
1580
|
-
|
|
1581
|
-
for (const dbIndex of dbIndexes) {
|
|
1582
|
-
let found = false;
|
|
1583
|
-
// Never try to drop `_id` index, MongoDB server doesn't allow it
|
|
1584
|
-
if (isDefaultIdIndex(dbIndex)) {
|
|
1585
|
-
continue;
|
|
1586
|
-
}
|
|
1587
|
-
|
|
1588
|
-
for (const [schemaIndexKeysObject, schemaIndexOptions] of schemaIndexes) {
|
|
1589
|
-
const options = decorateDiscriminatorIndexOptions(this.schema, utils.clone(schemaIndexOptions));
|
|
1590
|
-
applySchemaCollation(schemaIndexKeysObject, options, this.schema.options);
|
|
1591
|
-
|
|
1592
|
-
if (isIndexEqual(schemaIndexKeysObject, options, dbIndex)) {
|
|
1593
|
-
found = true;
|
|
1594
|
-
}
|
|
1595
|
-
}
|
|
1596
|
-
|
|
1597
|
-
if (!found) {
|
|
1598
|
-
toDrop.push(dbIndex.name);
|
|
1599
|
-
}
|
|
1600
|
-
}
|
|
1584
|
+
const toDrop = res.toDrop;
|
|
1601
1585
|
|
|
1602
1586
|
if (toDrop.length === 0) {
|
|
1603
1587
|
return cb(null, []);
|
package/lib/query.js
CHANGED
|
@@ -124,7 +124,10 @@ function Query(conditions, options, model, collection) {
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
// inherit mquery
|
|
127
|
-
mquery.call(this,
|
|
127
|
+
mquery.call(this, null, options);
|
|
128
|
+
if (collection) {
|
|
129
|
+
this.collection(collection);
|
|
130
|
+
}
|
|
128
131
|
|
|
129
132
|
if (conditions) {
|
|
130
133
|
this.find(conditions);
|
package/lib/queryhelpers.js
CHANGED
|
@@ -226,7 +226,9 @@ exports.applyPaths = function applyPaths(fields, schema) {
|
|
|
226
226
|
const addedPaths = [];
|
|
227
227
|
schema.eachPath(function(path, type) {
|
|
228
228
|
if (prefix) path = prefix + '.' + path;
|
|
229
|
-
|
|
229
|
+
if (type.$isSchemaMap || path.endsWith('.$*')) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
230
232
|
let addedPath = analyzePath(path, type);
|
|
231
233
|
// arrays
|
|
232
234
|
if (addedPath == null && !Array.isArray(type) && type.$isMongooseArray && !type.$isMongooseDocumentArray) {
|
|
@@ -248,7 +250,6 @@ exports.applyPaths = function applyPaths(fields, schema) {
|
|
|
248
250
|
}
|
|
249
251
|
}
|
|
250
252
|
});
|
|
251
|
-
|
|
252
253
|
stack.pop();
|
|
253
254
|
return addedPaths;
|
|
254
255
|
}
|
package/lib/schema/decimal128.js
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
const SchemaType = require('../schematype');
|
|
8
8
|
const CastError = SchemaType.CastError;
|
|
9
|
-
const Decimal128Type = require('../types/decimal128');
|
|
10
9
|
const castDecimal128 = require('../cast/decimal128');
|
|
11
10
|
const utils = require('../utils');
|
|
11
|
+
const isBsonType = require('../helpers/isBsonType');
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Decimal128 SchemaType constructor.
|
|
@@ -105,7 +105,7 @@ Decimal128.cast = function cast(caster) {
|
|
|
105
105
|
*/
|
|
106
106
|
|
|
107
107
|
Decimal128._defaultCaster = v => {
|
|
108
|
-
if (v != null && !(v
|
|
108
|
+
if (v != null && !isBsonType(v, 'Decimal128')) {
|
|
109
109
|
throw new Error();
|
|
110
110
|
}
|
|
111
111
|
return v;
|
|
@@ -115,7 +115,7 @@ Decimal128._defaultCaster = v => {
|
|
|
115
115
|
* ignore
|
|
116
116
|
*/
|
|
117
117
|
|
|
118
|
-
Decimal128._checkRequired = v => v
|
|
118
|
+
Decimal128._checkRequired = v => isBsonType(v, 'Decimal128');
|
|
119
119
|
|
|
120
120
|
/**
|
|
121
121
|
* Override the function the required validator uses to check whether a string
|
|
@@ -164,7 +164,7 @@ Decimal128.prototype.checkRequired = function checkRequired(value, doc) {
|
|
|
164
164
|
|
|
165
165
|
Decimal128.prototype.cast = function(value, doc, init) {
|
|
166
166
|
if (SchemaType._isRef(this, value, doc, init)) {
|
|
167
|
-
if (value
|
|
167
|
+
if (isBsonType(value, 'Decimal128')) {
|
|
168
168
|
return value;
|
|
169
169
|
}
|
|
170
170
|
|
package/lib/schema/map.js
CHANGED
|
@@ -69,6 +69,14 @@ class Map extends SchemaType {
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
/**
|
|
73
|
+
* This schema type's name, to defend against minifiers that mangle
|
|
74
|
+
* function names.
|
|
75
|
+
*
|
|
76
|
+
* @api public
|
|
77
|
+
*/
|
|
78
|
+
Map.schemaName = 'Map';
|
|
79
|
+
|
|
72
80
|
Map.prototype.OptionsConstructor = SchemaMapOptions;
|
|
73
81
|
|
|
74
82
|
Map.defaultOptions = {};
|
package/lib/schema/objectid.js
CHANGED
|
@@ -9,6 +9,7 @@ const SchemaType = require('../schematype');
|
|
|
9
9
|
const castObjectId = require('../cast/objectid');
|
|
10
10
|
const getConstructorName = require('../helpers/getConstructorName');
|
|
11
11
|
const oid = require('../types/objectid');
|
|
12
|
+
const isBsonType = require('../helpers/isBsonType');
|
|
12
13
|
const utils = require('../utils');
|
|
13
14
|
|
|
14
15
|
const CastError = SchemaType.CastError;
|
|
@@ -113,7 +114,7 @@ ObjectId.prototype.auto = function(turnOn) {
|
|
|
113
114
|
* ignore
|
|
114
115
|
*/
|
|
115
116
|
|
|
116
|
-
ObjectId._checkRequired = v => v
|
|
117
|
+
ObjectId._checkRequired = v => isBsonType(v, 'ObjectID');
|
|
117
118
|
|
|
118
119
|
/*!
|
|
119
120
|
* ignore
|
|
@@ -161,7 +162,7 @@ ObjectId.cast = function cast(caster) {
|
|
|
161
162
|
*/
|
|
162
163
|
|
|
163
164
|
ObjectId._defaultCaster = v => {
|
|
164
|
-
if (!(v
|
|
165
|
+
if (!(isBsonType(v, 'ObjectID'))) {
|
|
165
166
|
throw new Error(v + ' is not an instance of ObjectId');
|
|
166
167
|
}
|
|
167
168
|
return v;
|
|
@@ -221,7 +222,7 @@ ObjectId.prototype.checkRequired = function checkRequired(value, doc) {
|
|
|
221
222
|
*/
|
|
222
223
|
|
|
223
224
|
ObjectId.prototype.cast = function(value, doc, init) {
|
|
224
|
-
if (!(value
|
|
225
|
+
if (!(isBsonType(value, 'ObjectID')) && SchemaType._isRef(this, value, doc, init)) {
|
|
225
226
|
// wait! we may need to cast this to a document
|
|
226
227
|
if ((getConstructorName(value) || '').toLowerCase() === 'objectid') {
|
|
227
228
|
return new oid(value.toHexString());
|
package/lib/schema/string.js
CHANGED
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
* Module dependencies.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
const { BSONRegExp } = require('bson');
|
|
8
7
|
const SchemaType = require('../schematype');
|
|
9
8
|
const MongooseError = require('../error/index');
|
|
10
9
|
const SchemaStringOptions = require('../options/SchemaStringOptions');
|
|
11
10
|
const castString = require('../cast/string');
|
|
12
11
|
const utils = require('../utils');
|
|
12
|
+
const isBsonType = require('../helpers/isBsonType');
|
|
13
13
|
|
|
14
14
|
const CastError = SchemaType.CastError;
|
|
15
15
|
|
|
@@ -677,7 +677,7 @@ SchemaString.prototype.castForQuery = function($conditional, val) {
|
|
|
677
677
|
return handler.call(this, val);
|
|
678
678
|
}
|
|
679
679
|
val = $conditional;
|
|
680
|
-
if (Object.prototype.toString.call(val) === '[object RegExp]' || val
|
|
680
|
+
if (Object.prototype.toString.call(val) === '[object RegExp]' || isBsonType(val, 'BSONRegExp')) {
|
|
681
681
|
return val;
|
|
682
682
|
}
|
|
683
683
|
|