mongoose 6.3.4 → 6.3.7
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 +37 -24
- package/lib/error/index.js +2 -2
- package/lib/helpers/clone.js +7 -1
- 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/schematype/handleImmutable.js +2 -1
- package/lib/helpers/topology/isAtlas.js +15 -2
- package/lib/helpers/update/applyTimestampsToChildren.js +4 -0
- package/lib/helpers/update/castArrayFilters.js +3 -0
- package/lib/index.js +4 -3
- package/lib/options/SchemaTypeOptions.js +13 -0
- package/lib/query.js +4 -1
- package/lib/schema/SubdocumentPath.js +8 -1
- package/lib/schema/decimal128.js +4 -4
- package/lib/schema/documentarray.js +2 -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 +33 -2
- package/lib/schematype.js +1 -0
- 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 +17 -15
- 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 +91 -71
- package/types/document.d.ts +1 -1
- package/types/error.d.ts +5 -1
- package/types/helpers.d.ts +32 -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 +427 -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/CHANGELOG.md +0 -7300
- package/History.md +0 -1
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
|
@@ -79,7 +79,6 @@ function Document(obj, fields, skipId, options) {
|
|
|
79
79
|
options = skipId;
|
|
80
80
|
skipId = options.skipId;
|
|
81
81
|
}
|
|
82
|
-
options = Object.assign({}, options);
|
|
83
82
|
|
|
84
83
|
// Support `browserDocument.js` syntax
|
|
85
84
|
if (this.$__schema == null) {
|
|
@@ -93,9 +92,9 @@ function Document(obj, fields, skipId, options) {
|
|
|
93
92
|
}
|
|
94
93
|
|
|
95
94
|
this.$__ = new InternalCache();
|
|
96
|
-
this.$isNew =
|
|
95
|
+
this.$isNew = options && options.isNew != null ? options.isNew : true;
|
|
97
96
|
|
|
98
|
-
if (options.priorDoc != null) {
|
|
97
|
+
if (options && options.priorDoc != null) {
|
|
99
98
|
this.$__.priorDoc = options.priorDoc;
|
|
100
99
|
}
|
|
101
100
|
|
|
@@ -108,18 +107,20 @@ function Document(obj, fields, skipId, options) {
|
|
|
108
107
|
}
|
|
109
108
|
|
|
110
109
|
let defaults = true;
|
|
111
|
-
if (options.defaults !== undefined) {
|
|
110
|
+
if (options && options.defaults !== undefined) {
|
|
112
111
|
this.$__.defaults = options.defaults;
|
|
113
112
|
defaults = options.defaults;
|
|
114
113
|
}
|
|
115
114
|
|
|
116
115
|
const schema = this.$__schema;
|
|
117
116
|
|
|
117
|
+
let strict;
|
|
118
118
|
if (typeof fields === 'boolean' || fields === 'throw') {
|
|
119
119
|
this.$__.strictMode = fields;
|
|
120
|
+
strict = fields;
|
|
120
121
|
fields = undefined;
|
|
121
122
|
} else {
|
|
122
|
-
|
|
123
|
+
strict = schema.options.strict;
|
|
123
124
|
if (fields != null) {
|
|
124
125
|
this.$__.selected = fields;
|
|
125
126
|
}
|
|
@@ -136,7 +137,6 @@ function Document(obj, fields, skipId, options) {
|
|
|
136
137
|
// excluded fields
|
|
137
138
|
if (utils.isPOJO(fields)) {
|
|
138
139
|
exclude = isExclusive(fields);
|
|
139
|
-
|
|
140
140
|
this.$__.fields = fields;
|
|
141
141
|
this.$__.exclude = exclude;
|
|
142
142
|
}
|
|
@@ -170,15 +170,15 @@ function Document(obj, fields, skipId, options) {
|
|
|
170
170
|
// Function defaults get applied **after** setting initial values so they
|
|
171
171
|
// see the full doc rather than an empty one, unless they opt out.
|
|
172
172
|
// Re: gh-3781, gh-6155
|
|
173
|
-
if (options.willInit && defaults) {
|
|
173
|
+
if (options && options.willInit && defaults) {
|
|
174
174
|
if (options.skipDefaults) {
|
|
175
175
|
this.$__.skipDefaults = options.skipDefaults;
|
|
176
176
|
}
|
|
177
177
|
} else if (defaults) {
|
|
178
|
-
$__applyDefaults(this, fields, exclude, hasIncludedChildren, false, options.skipDefaults);
|
|
178
|
+
$__applyDefaults(this, fields, exclude, hasIncludedChildren, false, options && options.skipDefaults);
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
if (!
|
|
181
|
+
if (!strict && obj) {
|
|
182
182
|
const _this = this;
|
|
183
183
|
const keys = Object.keys(this._doc);
|
|
184
184
|
|
|
@@ -641,7 +641,11 @@ Document.prototype.$__buildDoc = function(obj, fields, skipId, exclude, hasInclu
|
|
|
641
641
|
for (let i = 0; i < len; ++i) {
|
|
642
642
|
const piece = path[i];
|
|
643
643
|
|
|
644
|
-
|
|
644
|
+
if (!curPath.length) {
|
|
645
|
+
curPath = piece;
|
|
646
|
+
} else {
|
|
647
|
+
curPath += '.' + piece;
|
|
648
|
+
}
|
|
645
649
|
|
|
646
650
|
// support excluding intermediary levels
|
|
647
651
|
if (exclude === true) {
|
|
@@ -1045,8 +1049,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1045
1049
|
type = undefined;
|
|
1046
1050
|
}
|
|
1047
1051
|
|
|
1048
|
-
|
|
1049
|
-
const merge = options.merge;
|
|
1052
|
+
const merge = options && options.merge;
|
|
1050
1053
|
const adhoc = type && type !== true;
|
|
1051
1054
|
const constructing = type === true;
|
|
1052
1055
|
let adhocs;
|
|
@@ -1056,7 +1059,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1056
1059
|
let key;
|
|
1057
1060
|
let prefix;
|
|
1058
1061
|
|
|
1059
|
-
const strict = 'strict' in options
|
|
1062
|
+
const strict = options && 'strict' in options
|
|
1060
1063
|
? options.strict
|
|
1061
1064
|
: this.$__.strictMode;
|
|
1062
1065
|
|
|
@@ -1087,7 +1090,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1087
1090
|
|
|
1088
1091
|
// `_skipMinimizeTopLevel` is because we may have deleted the top-level
|
|
1089
1092
|
// nested key to ensure key order.
|
|
1090
|
-
const _skipMinimizeTopLevel = options._skipMinimizeTopLevel || false;
|
|
1093
|
+
const _skipMinimizeTopLevel = options && options._skipMinimizeTopLevel || false;
|
|
1091
1094
|
if (len === 0 && _skipMinimizeTopLevel) {
|
|
1092
1095
|
delete options._skipMinimizeTopLevel;
|
|
1093
1096
|
if (val) {
|
|
@@ -1378,7 +1381,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1378
1381
|
})();
|
|
1379
1382
|
|
|
1380
1383
|
let didPopulate = false;
|
|
1381
|
-
if (refMatches && val instanceof Document) {
|
|
1384
|
+
if (refMatches && val instanceof Document && (!val.$__.wasPopulated || utils.deepEqual(val.$__.wasPopulated.value, val._id))) {
|
|
1382
1385
|
const unpopulatedValue = (schema && schema.$isSingleNested) ? schema.cast(val, this) : val._id;
|
|
1383
1386
|
this.$populated(path, unpopulatedValue, { [populateModelSymbol]: val.constructor });
|
|
1384
1387
|
val.$__.wasPopulated = { value: unpopulatedValue };
|
|
@@ -1565,7 +1568,7 @@ Document.prototype.set = Document.prototype.$set;
|
|
|
1565
1568
|
*/
|
|
1566
1569
|
|
|
1567
1570
|
Document.prototype.$__shouldModify = function(pathToMark, path, options, constructing, parts, schema, val, priorVal) {
|
|
1568
|
-
if (options._skipMarkModified) {
|
|
1571
|
+
if (options && options._skipMarkModified) {
|
|
1569
1572
|
return false;
|
|
1570
1573
|
}
|
|
1571
1574
|
if (this.$isNew) {
|
|
@@ -3464,9 +3467,9 @@ Document.prototype.$toObject = function(options, json) {
|
|
|
3464
3467
|
|
|
3465
3468
|
const path = json ? 'toJSON' : 'toObject';
|
|
3466
3469
|
const baseOptions = this.constructor &&
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
+
this.constructor.base &&
|
|
3471
|
+
this.constructor.base.options &&
|
|
3472
|
+
get(this.constructor.base.options, path) || {};
|
|
3470
3473
|
const schemaOptions = this.$__schema && this.$__schema.options || {};
|
|
3471
3474
|
// merge base default options with Schema's set default options if available.
|
|
3472
3475
|
// `clone` is necessary here because `utils.options` directly modifies the second input.
|
|
@@ -3474,8 +3477,8 @@ Document.prototype.$toObject = function(options, json) {
|
|
|
3474
3477
|
defaultOptions = utils.options(defaultOptions, clone(schemaOptions[path] || {}));
|
|
3475
3478
|
|
|
3476
3479
|
// If options do not exist or is not an object, set it to empty object
|
|
3477
|
-
options = utils.isPOJO(options) ?
|
|
3478
|
-
options._calledWithOptions = options._calledWithOptions ||
|
|
3480
|
+
options = utils.isPOJO(options) ? { ...options } : {};
|
|
3481
|
+
options._calledWithOptions = options._calledWithOptions || { ...options };
|
|
3479
3482
|
|
|
3480
3483
|
let _minimize;
|
|
3481
3484
|
if (options._calledWithOptions.minimize != null) {
|
|
@@ -3499,11 +3502,12 @@ Document.prototype.$toObject = function(options, json) {
|
|
|
3499
3502
|
// `clone()` will recursively call `$toObject()` on embedded docs, so we
|
|
3500
3503
|
// need the original options the user passed in, plus `_isNested` and
|
|
3501
3504
|
// `_parentOptions` for checking whether we need to depopulate.
|
|
3502
|
-
const cloneOptions = Object.assign(
|
|
3505
|
+
const cloneOptions = Object.assign({}, options, {
|
|
3503
3506
|
_isNested: true,
|
|
3504
3507
|
json: json,
|
|
3505
3508
|
minimize: _minimize,
|
|
3506
|
-
flattenMaps: flattenMaps
|
|
3509
|
+
flattenMaps: flattenMaps,
|
|
3510
|
+
_seen: (options && options._seen) || new Map()
|
|
3507
3511
|
});
|
|
3508
3512
|
|
|
3509
3513
|
if (utils.hasUserDefinedProperty(options, 'getters')) {
|
|
@@ -3928,12 +3932,19 @@ function applySchemaTypeTransforms(self, json) {
|
|
|
3928
3932
|
const schematype = schema.paths[path];
|
|
3929
3933
|
if (typeof schematype.options.transform === 'function') {
|
|
3930
3934
|
const val = self.$get(path);
|
|
3935
|
+
if (val === undefined) {
|
|
3936
|
+
continue;
|
|
3937
|
+
}
|
|
3931
3938
|
const transformedValue = schematype.options.transform.call(self, val);
|
|
3932
3939
|
throwErrorIfPromise(path, transformedValue);
|
|
3933
3940
|
utils.setValue(path, transformedValue, json);
|
|
3934
3941
|
} else if (schematype.$embeddedSchemaType != null &&
|
|
3935
3942
|
typeof schematype.$embeddedSchemaType.options.transform === 'function') {
|
|
3936
|
-
const
|
|
3943
|
+
const val = self.$get(path);
|
|
3944
|
+
if (val === undefined) {
|
|
3945
|
+
continue;
|
|
3946
|
+
}
|
|
3947
|
+
const vals = [].concat(val);
|
|
3937
3948
|
const transform = schematype.$embeddedSchemaType.options.transform;
|
|
3938
3949
|
for (let i = 0; i < vals.length; ++i) {
|
|
3939
3950
|
const transformedValue = transform.call(self, vals[i]);
|
|
@@ -4226,8 +4237,10 @@ Document.prototype.populate = function populate() {
|
|
|
4226
4237
|
* @api public
|
|
4227
4238
|
* @return {Array<Document>} array of populated documents. Empty array if there are no populated documents associated with this document.
|
|
4228
4239
|
* @memberOf Document
|
|
4240
|
+
* @method $getPopulatedDocs
|
|
4229
4241
|
* @instance
|
|
4230
4242
|
*/
|
|
4243
|
+
|
|
4231
4244
|
Document.prototype.$getPopulatedDocs = function $getPopulatedDocs() {
|
|
4232
4245
|
let keys = [];
|
|
4233
4246
|
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
|
|
|
@@ -119,9 +119,15 @@ module.exports = clone;
|
|
|
119
119
|
function cloneObject(obj, options, isArrayChild) {
|
|
120
120
|
const minimize = options && options.minimize;
|
|
121
121
|
const omitUndefined = options && options.omitUndefined;
|
|
122
|
+
const seen = options && options._seen;
|
|
122
123
|
const ret = {};
|
|
123
124
|
let hasKeys;
|
|
124
125
|
|
|
126
|
+
if (seen && seen.has(obj)) {
|
|
127
|
+
return seen.get(obj);
|
|
128
|
+
} else if (seen) {
|
|
129
|
+
seen.set(obj, ret);
|
|
130
|
+
}
|
|
125
131
|
if (trustedSymbol in obj) {
|
|
126
132
|
ret[trustedSymbol] = obj[trustedSymbol];
|
|
127
133
|
}
|
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
|
};
|
|
@@ -40,7 +40,8 @@ function createImmutableSetter(path, immutable) {
|
|
|
40
40
|
const _value = this.$__.priorDoc != null ?
|
|
41
41
|
this.$__.priorDoc.$__getValue(path) :
|
|
42
42
|
this.$__getValue(path);
|
|
43
|
-
|
|
43
|
+
const strict = this.$__.strictMode == null ? this.$__schema.options.strict : this.$__.strictMode;
|
|
44
|
+
if (strict === 'throw' && v !== _value) {
|
|
44
45
|
throw new StrictModeError(path, 'Path `' + path + '` is immutable ' +
|
|
45
46
|
'and strict mode is set to throw.', true);
|
|
46
47
|
}
|
|
@@ -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
|
}
|
|
@@ -15,6 +15,9 @@ module.exports = function castArrayFilters(query) {
|
|
|
15
15
|
if (query._mongooseOptions.strict != null) {
|
|
16
16
|
strictQuery = query._mongooseOptions.strict;
|
|
17
17
|
}
|
|
18
|
+
if (query.model && query.model.base.options.strictQuery != null) {
|
|
19
|
+
strictQuery = query.model.base.options.strictQuery;
|
|
20
|
+
}
|
|
18
21
|
if (schema._userProvidedOptions.strictQuery != null) {
|
|
19
22
|
strictQuery = schema._userProvidedOptions.strictQuery;
|
|
20
23
|
}
|
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
|
/**
|
|
@@ -119,6 +119,19 @@ Object.defineProperty(SchemaTypeOptions.prototype, 'default', opts);
|
|
|
119
119
|
|
|
120
120
|
Object.defineProperty(SchemaTypeOptions.prototype, 'ref', opts);
|
|
121
121
|
|
|
122
|
+
/**
|
|
123
|
+
* The path in the document that `populate()` should use to find the model
|
|
124
|
+
* to use.
|
|
125
|
+
*
|
|
126
|
+
* @api public
|
|
127
|
+
* @property ref
|
|
128
|
+
* @memberOf SchemaTypeOptions
|
|
129
|
+
* @type Function|String
|
|
130
|
+
* @instance
|
|
131
|
+
*/
|
|
132
|
+
|
|
133
|
+
Object.defineProperty(SchemaTypeOptions.prototype, 'refPath', opts);
|
|
134
|
+
|
|
122
135
|
/**
|
|
123
136
|
* Whether to include or exclude this path by default when loading documents
|
|
124
137
|
* using `find()`, `findOne()`, etc.
|
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);
|
|
@@ -33,6 +33,13 @@ module.exports = SubdocumentPath;
|
|
|
33
33
|
*/
|
|
34
34
|
|
|
35
35
|
function SubdocumentPath(schema, path, options) {
|
|
36
|
+
const schemaTypeIdOption = SubdocumentPath.defaultOptions &&
|
|
37
|
+
SubdocumentPath.defaultOptions._id;
|
|
38
|
+
if (schemaTypeIdOption != null) {
|
|
39
|
+
options = options || {};
|
|
40
|
+
options._id = schemaTypeIdOption;
|
|
41
|
+
}
|
|
42
|
+
|
|
36
43
|
schema = handleIdOption(schema, options);
|
|
37
44
|
|
|
38
45
|
this.caster = _createConstructor(schema);
|
|
@@ -160,7 +167,7 @@ SubdocumentPath.prototype.cast = function(val, doc, init, priorVal, options) {
|
|
|
160
167
|
}
|
|
161
168
|
return obj;
|
|
162
169
|
}, null);
|
|
163
|
-
options = Object.assign({}, options, { priorDoc: priorVal });
|
|
170
|
+
options = priorVal != null ? Object.assign({}, options, { priorDoc: priorVal }) : options;
|
|
164
171
|
if (init) {
|
|
165
172
|
subdoc = new Constructor(void 0, selected, doc);
|
|
166
173
|
subdoc.$init(val);
|
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
|
|
|
@@ -391,8 +391,6 @@ DocumentArrayPath.prototype.cast = function(value, doc, init, prev, options) {
|
|
|
391
391
|
let selected;
|
|
392
392
|
let subdoc;
|
|
393
393
|
|
|
394
|
-
options = options || {};
|
|
395
|
-
|
|
396
394
|
if (!Array.isArray(value)) {
|
|
397
395
|
if (!init && !DocumentArrayPath.options.castNonArrays) {
|
|
398
396
|
throw new CastError('DocumentArray', value, this.path, null, this);
|
|
@@ -407,7 +405,7 @@ DocumentArrayPath.prototype.cast = function(value, doc, init, prev, options) {
|
|
|
407
405
|
|
|
408
406
|
// We need to create a new array, otherwise change tracking will
|
|
409
407
|
// update the old doc (gh-4449)
|
|
410
|
-
if (!options.skipDocumentArrayCast || utils.isMongooseDocumentArray(value)) {
|
|
408
|
+
if (!options || !options.skipDocumentArrayCast || utils.isMongooseDocumentArray(value)) {
|
|
411
409
|
value = new MongooseDocumentArray(value, this.path, doc);
|
|
412
410
|
}
|
|
413
411
|
|
|
@@ -415,7 +413,7 @@ DocumentArrayPath.prototype.cast = function(value, doc, init, prev, options) {
|
|
|
415
413
|
value[arrayAtomicsSymbol] = prev[arrayAtomicsSymbol] || {};
|
|
416
414
|
}
|
|
417
415
|
|
|
418
|
-
if (options.arrayPathIndex != null) {
|
|
416
|
+
if (options && options.arrayPathIndex != null) {
|
|
419
417
|
value[arrayPathSymbol] = this.path + '.' + options.arrayPathIndex;
|
|
420
418
|
}
|
|
421
419
|
|
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 = {};
|