mongoose 6.3.7 → 6.4.0
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 +61 -34
- package/lib/connection.js +50 -9
- package/lib/document.js +55 -18
- package/lib/error/disconnected.js +3 -4
- package/lib/helpers/schematype/handleImmutable.js +1 -2
- package/lib/helpers/timestamps/setupTimestamps.js +4 -1
- package/lib/helpers/updateValidators.js +11 -18
- package/lib/index.js +108 -33
- package/lib/model.js +1 -1
- package/lib/query.js +61 -6
- package/lib/schema/SubdocumentPath.js +1 -1
- package/lib/schema/documentarray.js +14 -2
- package/lib/schema.js +3 -4
- package/lib/schematype.js +0 -1
- package/lib/statemachine.js +13 -0
- package/lib/utils.js +3 -0
- package/lib/validoptions.js +1 -0
- package/package.json +3 -3
- package/tsconfig.json +1 -0
- package/types/aggregate.d.ts +3 -0
- package/types/connection.d.ts +5 -0
- package/types/document.d.ts +5 -2
- package/types/expressions.d.ts +2880 -0
- package/types/index.d.ts +43 -14
- package/types/inferschematype.d.ts +155 -0
- package/types/models.d.ts +84 -69
- package/types/mongooseoptions.d.ts +8 -0
- package/types/pipelinestage.d.ts +76 -80
- package/types/query.d.ts +1 -1
- package/types/schemaoptions.d.ts +21 -3
- package/types/utility.d.ts +2 -0
package/.eslintrc.json
CHANGED
|
@@ -4,43 +4,70 @@
|
|
|
4
4
|
],
|
|
5
5
|
"ignorePatterns": [
|
|
6
6
|
"docs",
|
|
7
|
+
"tools",
|
|
7
8
|
"dist",
|
|
8
|
-
"
|
|
9
|
+
"website.js",
|
|
10
|
+
"test/files/*",
|
|
11
|
+
"benchmarks"
|
|
9
12
|
],
|
|
10
|
-
"overrides": [
|
|
11
|
-
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
13
|
+
"overrides": [
|
|
14
|
+
{
|
|
15
|
+
"files": [
|
|
16
|
+
"**/*.{ts,tsx}"
|
|
17
|
+
],
|
|
18
|
+
"extends": [
|
|
19
|
+
"plugin:@typescript-eslint/eslint-recommended",
|
|
20
|
+
"plugin:@typescript-eslint/recommended"
|
|
21
|
+
],
|
|
22
|
+
"plugins": [
|
|
23
|
+
"@typescript-eslint"
|
|
24
|
+
],
|
|
25
|
+
"rules": {
|
|
26
|
+
"@typescript-eslint/triple-slash-reference": "off",
|
|
27
|
+
"spaced-comment": [
|
|
28
|
+
"error",
|
|
29
|
+
"always",
|
|
30
|
+
{
|
|
31
|
+
"block": {
|
|
32
|
+
"markers": [
|
|
33
|
+
"!"
|
|
34
|
+
],
|
|
35
|
+
"balanced": true
|
|
36
|
+
},
|
|
37
|
+
"markers": [
|
|
38
|
+
"/"
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
43
|
+
"@typescript-eslint/ban-types": "off",
|
|
44
|
+
"@typescript-eslint/no-unused-vars": "off",
|
|
45
|
+
"@typescript-eslint/explicit-module-boundary-types": "off",
|
|
46
|
+
"@typescript-eslint/indent": [
|
|
47
|
+
"error",
|
|
48
|
+
2,
|
|
49
|
+
{
|
|
50
|
+
"SwitchCase": 1
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"@typescript-eslint/prefer-optional-chain": "error",
|
|
54
|
+
"@typescript-eslint/brace-style": "error",
|
|
55
|
+
"@typescript-eslint/no-dupe-class-members": "error",
|
|
56
|
+
"@typescript-eslint/no-redeclare": "error",
|
|
57
|
+
"@typescript-eslint/type-annotation-spacing": "error",
|
|
58
|
+
"@typescript-eslint/object-curly-spacing": [
|
|
59
|
+
"error",
|
|
60
|
+
"always"
|
|
61
|
+
],
|
|
62
|
+
"@typescript-eslint/semi": "error",
|
|
63
|
+
"@typescript-eslint/space-before-function-paren": [
|
|
64
|
+
"error",
|
|
65
|
+
"never"
|
|
66
|
+
],
|
|
67
|
+
"@typescript-eslint/space-infix-ops": "off"
|
|
68
|
+
}
|
|
42
69
|
}
|
|
43
|
-
|
|
70
|
+
],
|
|
44
71
|
"plugins": [
|
|
45
72
|
"mocha-no-only"
|
|
46
73
|
],
|
package/lib/connection.js
CHANGED
|
@@ -9,6 +9,7 @@ const EventEmitter = require('events').EventEmitter;
|
|
|
9
9
|
const Schema = require('./schema');
|
|
10
10
|
const STATES = require('./connectionstate');
|
|
11
11
|
const MongooseError = require('./error/index');
|
|
12
|
+
const DisconnectedError = require('./error/disconnected');
|
|
12
13
|
const SyncIndexesError = require('./error/syncIndexes');
|
|
13
14
|
const PromiseProvider = require('./promise_provider');
|
|
14
15
|
const ServerSelectionError = require('./error/serverSelection');
|
|
@@ -565,8 +566,7 @@ function _wrapConnHelper(fn) {
|
|
|
565
566
|
const argsWithoutCb = typeof cb === 'function' ?
|
|
566
567
|
Array.prototype.slice.call(arguments, 0, arguments.length - 1) :
|
|
567
568
|
Array.prototype.slice.call(arguments);
|
|
568
|
-
const disconnectedError = new
|
|
569
|
-
' was disconnected when calling `' + fn.name + '`');
|
|
569
|
+
const disconnectedError = new DisconnectedError(this.id, fn.name);
|
|
570
570
|
|
|
571
571
|
return promiseOrCallback(cb, cb => {
|
|
572
572
|
immediate(() => {
|
|
@@ -697,6 +697,18 @@ Connection.prototype.openUri = function(uri, options, callback) {
|
|
|
697
697
|
typeof callback + '"');
|
|
698
698
|
}
|
|
699
699
|
|
|
700
|
+
if (this._destroyCalled) {
|
|
701
|
+
const error = 'Connection has been closed and destroyed, and cannot be used for re-opening the connection. ' +
|
|
702
|
+
'Please create a new connection with `mongoose.createConnection()` or `mongoose.connect()`.';
|
|
703
|
+
if (typeof callback === 'function') {
|
|
704
|
+
callback(error);
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
else {
|
|
708
|
+
throw new MongooseError(error);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
|
|
700
712
|
if (this.readyState === STATES.connecting || this.readyState === STATES.connected) {
|
|
701
713
|
if (this._connectionString !== uri) {
|
|
702
714
|
throw new MongooseError('Can\'t call `openUri()` on an active connection with ' +
|
|
@@ -901,6 +913,23 @@ function _setClient(conn, client, options, dbName) {
|
|
|
901
913
|
}
|
|
902
914
|
}
|
|
903
915
|
|
|
916
|
+
Connection.prototype.destroy = function(force, callback) {
|
|
917
|
+
if (typeof force === 'function') {
|
|
918
|
+
callback = force;
|
|
919
|
+
force = false;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
if (force != null && typeof force === 'object') {
|
|
923
|
+
this.$wasForceClosed = !!force.force;
|
|
924
|
+
} else {
|
|
925
|
+
this.$wasForceClosed = !!force;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
return promiseOrCallback(callback, cb => {
|
|
929
|
+
this._close(force, true, cb);
|
|
930
|
+
});
|
|
931
|
+
};
|
|
932
|
+
|
|
904
933
|
/**
|
|
905
934
|
* Closes the connection
|
|
906
935
|
*
|
|
@@ -923,7 +952,7 @@ Connection.prototype.close = function(force, callback) {
|
|
|
923
952
|
}
|
|
924
953
|
|
|
925
954
|
return promiseOrCallback(callback, cb => {
|
|
926
|
-
this._close(force, cb);
|
|
955
|
+
this._close(force, false, cb);
|
|
927
956
|
});
|
|
928
957
|
};
|
|
929
958
|
|
|
@@ -931,19 +960,26 @@ Connection.prototype.close = function(force, callback) {
|
|
|
931
960
|
* Handles closing the connection
|
|
932
961
|
*
|
|
933
962
|
* @param {Boolean} force
|
|
963
|
+
* @param {Boolean} destroy
|
|
934
964
|
* @param {Function} callback
|
|
935
965
|
* @api private
|
|
936
966
|
*/
|
|
937
|
-
Connection.prototype._close = function(force, callback) {
|
|
967
|
+
Connection.prototype._close = function(force, destroy, callback) {
|
|
938
968
|
const _this = this;
|
|
939
969
|
const closeCalled = this._closeCalled;
|
|
940
970
|
this._closeCalled = true;
|
|
971
|
+
this._destroyCalled = destroy;
|
|
941
972
|
if (this.client != null) {
|
|
942
973
|
this.client._closeCalled = true;
|
|
974
|
+
this.client._destroyCalled = destroy;
|
|
943
975
|
}
|
|
944
976
|
|
|
977
|
+
const conn = this;
|
|
945
978
|
switch (this.readyState) {
|
|
946
979
|
case STATES.disconnected:
|
|
980
|
+
if (destroy && this.base.connections.indexOf(conn) !== -1) {
|
|
981
|
+
this.base.connections.splice(this.base.connections.indexOf(conn), 1);
|
|
982
|
+
}
|
|
947
983
|
if (closeCalled) {
|
|
948
984
|
callback();
|
|
949
985
|
} else {
|
|
@@ -963,6 +999,9 @@ Connection.prototype._close = function(force, callback) {
|
|
|
963
999
|
if (err) {
|
|
964
1000
|
return callback(err);
|
|
965
1001
|
}
|
|
1002
|
+
if (destroy && _this.base.connections.indexOf(conn) !== -1) {
|
|
1003
|
+
_this.base.connections.splice(_this.base.connections.indexOf(conn), 1);
|
|
1004
|
+
}
|
|
966
1005
|
_this.onClose(force);
|
|
967
1006
|
callback(null);
|
|
968
1007
|
});
|
|
@@ -970,12 +1009,15 @@ Connection.prototype._close = function(force, callback) {
|
|
|
970
1009
|
break;
|
|
971
1010
|
case STATES.connecting:
|
|
972
1011
|
this.once('open', function() {
|
|
973
|
-
_this.close(callback);
|
|
1012
|
+
destroy ? _this.destroy(force, callback) : _this.close(force, callback);
|
|
974
1013
|
});
|
|
975
1014
|
break;
|
|
976
1015
|
|
|
977
1016
|
case STATES.disconnecting:
|
|
978
1017
|
this.once('close', function() {
|
|
1018
|
+
if (destroy && _this.base.connections.indexOf(conn) !== -1) {
|
|
1019
|
+
_this.base.connections.splice(_this.base.connections.indexOf(conn), 1);
|
|
1020
|
+
}
|
|
979
1021
|
callback();
|
|
980
1022
|
});
|
|
981
1023
|
break;
|
|
@@ -1004,7 +1046,7 @@ Connection.prototype.onClose = function(force) {
|
|
|
1004
1046
|
this.emit('close', force);
|
|
1005
1047
|
|
|
1006
1048
|
for (const db of this.otherDbs) {
|
|
1007
|
-
db.close({ force: force, skipCloseClient: true });
|
|
1049
|
+
this._destroyCalled ? db.destroy({ force: force, skipCloseClient: true }) : db.close({ force: force, skipCloseClient: true });
|
|
1008
1050
|
}
|
|
1009
1051
|
};
|
|
1010
1052
|
|
|
@@ -1026,7 +1068,7 @@ Connection.prototype.collection = function(name, options) {
|
|
|
1026
1068
|
};
|
|
1027
1069
|
options = Object.assign({}, defaultOptions, options ? utils.clone(options) : {});
|
|
1028
1070
|
options.$wasForceClosed = this.$wasForceClosed;
|
|
1029
|
-
const Collection = driver.get().Collection;
|
|
1071
|
+
const Collection = this.base && this.base.__driver && this.base.__driver.Collection || driver.get().Collection;
|
|
1030
1072
|
if (!(name in this.collections)) {
|
|
1031
1073
|
this.collections[name] = new Collection(name, this, options);
|
|
1032
1074
|
}
|
|
@@ -1260,8 +1302,7 @@ Connection.prototype.deleteModel = function(name) {
|
|
|
1260
1302
|
*/
|
|
1261
1303
|
|
|
1262
1304
|
Connection.prototype.watch = function(pipeline, options) {
|
|
1263
|
-
const disconnectedError = new
|
|
1264
|
-
' was disconnected when calling `watch()`');
|
|
1305
|
+
const disconnectedError = new DisconnectedError(this.id, 'watch');
|
|
1265
1306
|
|
|
1266
1307
|
const changeStreamThunk = cb => {
|
|
1267
1308
|
immediate(() => {
|
package/lib/document.js
CHANGED
|
@@ -79,6 +79,7 @@ function Document(obj, fields, skipId, options) {
|
|
|
79
79
|
options = skipId;
|
|
80
80
|
skipId = options.skipId;
|
|
81
81
|
}
|
|
82
|
+
options = Object.assign({}, options);
|
|
82
83
|
|
|
83
84
|
// Support `browserDocument.js` syntax
|
|
84
85
|
if (this.$__schema == null) {
|
|
@@ -92,9 +93,9 @@ function Document(obj, fields, skipId, options) {
|
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
this.$__ = new InternalCache();
|
|
95
|
-
this.$isNew =
|
|
96
|
+
this.$isNew = 'isNew' in options ? options.isNew : true;
|
|
96
97
|
|
|
97
|
-
if (options
|
|
98
|
+
if (options.priorDoc != null) {
|
|
98
99
|
this.$__.priorDoc = options.priorDoc;
|
|
99
100
|
}
|
|
100
101
|
|
|
@@ -107,20 +108,18 @@ function Document(obj, fields, skipId, options) {
|
|
|
107
108
|
}
|
|
108
109
|
|
|
109
110
|
let defaults = true;
|
|
110
|
-
if (options
|
|
111
|
+
if (options.defaults !== undefined) {
|
|
111
112
|
this.$__.defaults = options.defaults;
|
|
112
113
|
defaults = options.defaults;
|
|
113
114
|
}
|
|
114
115
|
|
|
115
116
|
const schema = this.$__schema;
|
|
116
117
|
|
|
117
|
-
let strict;
|
|
118
118
|
if (typeof fields === 'boolean' || fields === 'throw') {
|
|
119
119
|
this.$__.strictMode = fields;
|
|
120
|
-
strict = fields;
|
|
121
120
|
fields = undefined;
|
|
122
121
|
} else {
|
|
123
|
-
|
|
122
|
+
this.$__.strictMode = schema.options.strict;
|
|
124
123
|
if (fields != null) {
|
|
125
124
|
this.$__.selected = fields;
|
|
126
125
|
}
|
|
@@ -170,15 +169,15 @@ function Document(obj, fields, skipId, options) {
|
|
|
170
169
|
// Function defaults get applied **after** setting initial values so they
|
|
171
170
|
// see the full doc rather than an empty one, unless they opt out.
|
|
172
171
|
// Re: gh-3781, gh-6155
|
|
173
|
-
if (options
|
|
172
|
+
if (options.willInit && defaults) {
|
|
174
173
|
if (options.skipDefaults) {
|
|
175
174
|
this.$__.skipDefaults = options.skipDefaults;
|
|
176
175
|
}
|
|
177
176
|
} else if (defaults) {
|
|
178
|
-
$__applyDefaults(this, fields, exclude, hasIncludedChildren, false, options
|
|
177
|
+
$__applyDefaults(this, fields, exclude, hasIncludedChildren, false, options.skipDefaults);
|
|
179
178
|
}
|
|
180
179
|
|
|
181
|
-
if (!
|
|
180
|
+
if (!this.$__.strictMode && obj) {
|
|
182
181
|
const _this = this;
|
|
183
182
|
const keys = Object.keys(this._doc);
|
|
184
183
|
|
|
@@ -2487,7 +2486,7 @@ function _getPathsToValidate(doc) {
|
|
|
2487
2486
|
const fullPathToSubdoc = subdoc.$__fullPathWithIndexes();
|
|
2488
2487
|
|
|
2489
2488
|
for (const p of paths) {
|
|
2490
|
-
if (p
|
|
2489
|
+
if (p == null || p.startsWith(fullPathToSubdoc + '.')) {
|
|
2491
2490
|
paths.delete(p);
|
|
2492
2491
|
}
|
|
2493
2492
|
}
|
|
@@ -2508,6 +2507,14 @@ function _getPathsToValidate(doc) {
|
|
|
2508
2507
|
continue;
|
|
2509
2508
|
}
|
|
2510
2509
|
|
|
2510
|
+
if (_pathType.$isMongooseDocumentArray) {
|
|
2511
|
+
for (const p of paths) {
|
|
2512
|
+
if (p == null || p.startsWith(_pathType.path + '.')) {
|
|
2513
|
+
paths.delete(p);
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
|
|
2511
2518
|
// Optimization: if primitive path with no validators, or array of primitives
|
|
2512
2519
|
// with no validators, skip validating this path entirely.
|
|
2513
2520
|
if (!_pathType.caster && _pathType.validators.length === 0) {
|
|
@@ -3146,8 +3153,7 @@ Document.prototype.$__reset = function reset() {
|
|
|
3146
3153
|
if (subdoc.$isDocumentArrayElement) {
|
|
3147
3154
|
if (!resetArrays.has(subdoc.parentArray())) {
|
|
3148
3155
|
const array = subdoc.parentArray();
|
|
3149
|
-
|
|
3150
|
-
this.$__.activePaths.init(fullPathWithIndexes.replace(/\.\d+$/, '').slice(-subdoc.$basePath - 1));
|
|
3156
|
+
this.$__.activePaths.clearPath(fullPathWithIndexes.replace(/\.\d+$/, '').slice(-subdoc.$basePath - 1));
|
|
3151
3157
|
array[arrayAtomicsBackupSymbol] = array[arrayAtomicsSymbol];
|
|
3152
3158
|
array[arrayAtomicsSymbol] = {};
|
|
3153
3159
|
|
|
@@ -3155,7 +3161,7 @@ Document.prototype.$__reset = function reset() {
|
|
|
3155
3161
|
}
|
|
3156
3162
|
} else {
|
|
3157
3163
|
if (subdoc.$parent() === this) {
|
|
3158
|
-
this.$__.activePaths.
|
|
3164
|
+
this.$__.activePaths.clearPath(subdoc.$basePath);
|
|
3159
3165
|
} else if (subdoc.$parent() != null && subdoc.$parent().$isSubdocument) {
|
|
3160
3166
|
// If map path underneath subdocument, may end up with a case where
|
|
3161
3167
|
// map path is modified but parent still needs to be reset. See gh-10295
|
|
@@ -3389,7 +3395,7 @@ Document.prototype.$getAllSubdocs = function() {
|
|
|
3389
3395
|
}, seed);
|
|
3390
3396
|
} else if (val && !Array.isArray(val) && val.$isSingleNested) {
|
|
3391
3397
|
seed = Object.keys(val._doc).reduce(function(seed, path) {
|
|
3392
|
-
return docReducer(val
|
|
3398
|
+
return docReducer(val, seed, path);
|
|
3393
3399
|
}, seed);
|
|
3394
3400
|
seed.push(val);
|
|
3395
3401
|
} else if (val && utils.isMongooseDocumentArray(val)) {
|
|
@@ -4263,10 +4269,10 @@ Document.prototype.$getPopulatedDocs = function $getPopulatedDocs() {
|
|
|
4263
4269
|
*
|
|
4264
4270
|
* #### Example:
|
|
4265
4271
|
*
|
|
4266
|
-
* Model.findOne().populate('author')
|
|
4267
|
-
*
|
|
4268
|
-
*
|
|
4269
|
-
*
|
|
4272
|
+
* const doc = await Model.findOne().populate('author');
|
|
4273
|
+
*
|
|
4274
|
+
* console.log(doc.author.name); // Dr.Seuss
|
|
4275
|
+
* console.log(doc.populated('author')); // '5144cf8050f071d979c118a7'
|
|
4270
4276
|
*
|
|
4271
4277
|
* If the path was not populated, returns `undefined`.
|
|
4272
4278
|
*
|
|
@@ -4320,6 +4326,37 @@ Document.prototype.populated = function(path, val, options) {
|
|
|
4320
4326
|
|
|
4321
4327
|
Document.prototype.$populated = Document.prototype.populated;
|
|
4322
4328
|
|
|
4329
|
+
/**
|
|
4330
|
+
* Throws an error if a given path is not populated
|
|
4331
|
+
*
|
|
4332
|
+
* #### Example:
|
|
4333
|
+
*
|
|
4334
|
+
* const doc = await Model.findOne().populate('author');
|
|
4335
|
+
*
|
|
4336
|
+
* doc.$assertPopulated('author'); // does not throw
|
|
4337
|
+
* doc.$assertPopulated('other path'); // throws an error
|
|
4338
|
+
*
|
|
4339
|
+
*
|
|
4340
|
+
* @param {String | Array<String>} path
|
|
4341
|
+
* @return {Document} this
|
|
4342
|
+
* @memberOf Document
|
|
4343
|
+
* @instance
|
|
4344
|
+
* @api public
|
|
4345
|
+
*/
|
|
4346
|
+
|
|
4347
|
+
Document.prototype.$assertPopulated = function $assertPopulated(paths) {
|
|
4348
|
+
if (Array.isArray(paths)) {
|
|
4349
|
+
paths.forEach(path => this.$assertPopulated(path));
|
|
4350
|
+
return this;
|
|
4351
|
+
}
|
|
4352
|
+
|
|
4353
|
+
if (!this.$populated(paths)) {
|
|
4354
|
+
throw new MongooseError(`Expected path "${paths}" to be populated`);
|
|
4355
|
+
}
|
|
4356
|
+
|
|
4357
|
+
return this;
|
|
4358
|
+
};
|
|
4359
|
+
|
|
4323
4360
|
/**
|
|
4324
4361
|
* Takes a populated field and returns it to its unpopulated state.
|
|
4325
4362
|
*
|
|
@@ -16,10 +16,9 @@ class DisconnectedError extends MongooseError {
|
|
|
16
16
|
/**
|
|
17
17
|
* @param {String} connectionString
|
|
18
18
|
*/
|
|
19
|
-
constructor(
|
|
20
|
-
super('
|
|
21
|
-
|
|
22
|
-
'`server.reconnectInterval` to something higher.');
|
|
19
|
+
constructor(id, fnName) {
|
|
20
|
+
super('Connection ' + id +
|
|
21
|
+
' was disconnected when calling `' + fnName + '()`');
|
|
23
22
|
}
|
|
24
23
|
}
|
|
25
24
|
|
|
@@ -40,8 +40,7 @@ function createImmutableSetter(path, immutable) {
|
|
|
40
40
|
const _value = this.$__.priorDoc != null ?
|
|
41
41
|
this.$__.priorDoc.$__getValue(path) :
|
|
42
42
|
this.$__getValue(path);
|
|
43
|
-
|
|
44
|
-
if (strict === 'throw' && v !== _value) {
|
|
43
|
+
if (this.$__.strictMode === 'throw' && v !== _value) {
|
|
45
44
|
throw new StrictModeError(path, 'Path `' + path + '` is immutable ' +
|
|
46
45
|
'and strict mode is set to throw.', true);
|
|
47
46
|
}
|
|
@@ -31,8 +31,11 @@ module.exports = function setupTimestamps(schema, timestamps) {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
if (createdAt && !schema.paths[createdAt]) {
|
|
34
|
-
|
|
34
|
+
const baseImmutableCreatedAt = schema.base.get('timestamps.createdAt.immutable');
|
|
35
|
+
const immutable = baseImmutableCreatedAt != null ? baseImmutableCreatedAt : true;
|
|
36
|
+
schemaAdditions[createdAt] = { [schema.options.typeKey || 'type']: Date, immutable };
|
|
35
37
|
}
|
|
38
|
+
|
|
36
39
|
schema.add(schemaAdditions);
|
|
37
40
|
|
|
38
41
|
schema.pre('save', function(next) {
|
|
@@ -125,26 +125,19 @@ module.exports = function(query, schema, castedDoc, options, callback) {
|
|
|
125
125
|
validatorsToExecute.push(function(callback) {
|
|
126
126
|
schemaPath.doValidate(v, function(err) {
|
|
127
127
|
if (err) {
|
|
128
|
-
err.
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
v.validate(function(err) {
|
|
134
|
-
if (err) {
|
|
135
|
-
if (err.errors) {
|
|
136
|
-
for (const key of Object.keys(err.errors)) {
|
|
137
|
-
const _err = err.errors[key];
|
|
138
|
-
_err.path = updates[i] + '.' + key;
|
|
139
|
-
validationErrors.push(_err);
|
|
140
|
-
}
|
|
141
|
-
} else {
|
|
142
|
-
err.path = updates[i];
|
|
143
|
-
validationErrors.push(err);
|
|
128
|
+
if (err.errors) {
|
|
129
|
+
for (const key of Object.keys(err.errors)) {
|
|
130
|
+
const _err = err.errors[key];
|
|
131
|
+
_err.path = updates[i] + '.' + key;
|
|
132
|
+
validationErrors.push(_err);
|
|
144
133
|
}
|
|
134
|
+
} else {
|
|
135
|
+
err.path = updates[i];
|
|
136
|
+
validationErrors.push(err);
|
|
145
137
|
}
|
|
146
|
-
|
|
147
|
-
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return callback(null);
|
|
148
141
|
}, context, { updateValidator: true });
|
|
149
142
|
});
|
|
150
143
|
} else {
|