mongoose 6.4.7 → 6.5.2
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/lib/connection.js +23 -3
- package/lib/cursor/ChangeStream.js +39 -1
- package/lib/document.js +129 -154
- package/lib/error/index.js +1 -0
- package/lib/error/validation.js +9 -0
- package/lib/helpers/document/applyDefaults.js +115 -0
- package/lib/helpers/document/cleanModifiedSubpaths.js +3 -3
- package/lib/helpers/document/compile.js +7 -6
- package/lib/helpers/firstKey.js +8 -0
- package/lib/helpers/model/applyDefaultsToPOJO.js +52 -0
- package/lib/helpers/model/castBulkWrite.js +1 -1
- package/lib/helpers/model/pushNestedArrayPaths.js +15 -0
- package/lib/helpers/populate/markArraySubdocsPopulated.js +1 -0
- package/lib/helpers/projection/hasIncludedChildren.js +1 -0
- package/lib/helpers/promiseOrCallback.js +24 -15
- package/lib/helpers/update/applyTimestampsToChildren.js +6 -2
- package/lib/index.js +2 -1
- package/lib/internal.js +3 -1
- package/lib/model.js +237 -95
- package/lib/options/SchemaArrayOptions.js +19 -0
- package/lib/options/SchemaNumberOptions.js +2 -0
- package/lib/options/SchemaObjectIdOptions.js +1 -0
- package/lib/plugins/trackTransaction.js +2 -2
- package/lib/query.js +30 -11
- package/lib/schema/SubdocumentPath.js +10 -0
- package/lib/schema/array.js +2 -1
- package/lib/schema/documentarray.js +14 -1
- package/lib/schema/string.js +3 -0
- package/lib/schema.js +22 -3
- package/lib/schematype.js +5 -1
- package/lib/statemachine.js +23 -9
- package/lib/types/buffer.js +23 -21
- package/lib/types/map.js +2 -0
- package/lib/utils.js +8 -0
- package/lib/validoptions.js +1 -0
- package/package.json +14 -14
- package/{build-browser.js → scripts/build-browser.js} +1 -1
- package/types/connection.d.ts +7 -1
- package/types/document.d.ts +8 -1
- package/types/expressions.d.ts +1 -1
- package/types/index.d.ts +31 -28
- package/types/inferschematype.d.ts +3 -20
- package/types/models.d.ts +53 -49
- package/types/mongooseoptions.d.ts +6 -0
- package/types/schemaoptions.d.ts +15 -4
- package/types/utility.d.ts +19 -0
- package/types/virtuals.d.ts +14 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
module.exports = function applyDefaults(doc, fields, exclude, hasIncludedChildren, isBeforeSetters, pathsToSkip) {
|
|
4
|
+
const paths = Object.keys(doc.$__schema.paths);
|
|
5
|
+
const plen = paths.length;
|
|
6
|
+
|
|
7
|
+
for (let i = 0; i < plen; ++i) {
|
|
8
|
+
let def;
|
|
9
|
+
let curPath = '';
|
|
10
|
+
const p = paths[i];
|
|
11
|
+
|
|
12
|
+
if (p === '_id' && doc.$__.skipId) {
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const type = doc.$__schema.paths[p];
|
|
17
|
+
const path = type.splitPath();
|
|
18
|
+
const len = path.length;
|
|
19
|
+
let included = false;
|
|
20
|
+
let doc_ = doc._doc;
|
|
21
|
+
for (let j = 0; j < len; ++j) {
|
|
22
|
+
if (doc_ == null) {
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const piece = path[j];
|
|
27
|
+
curPath += (!curPath.length ? '' : '.') + piece;
|
|
28
|
+
|
|
29
|
+
if (exclude === true) {
|
|
30
|
+
if (curPath in fields) {
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
} else if (exclude === false && fields && !included) {
|
|
34
|
+
const hasSubpaths = type.$isSingleNested || type.$isMongooseDocumentArray;
|
|
35
|
+
if (curPath in fields || (hasSubpaths && hasIncludedChildren != null && hasIncludedChildren[curPath])) {
|
|
36
|
+
included = true;
|
|
37
|
+
} else if (hasIncludedChildren != null && !hasIncludedChildren[curPath]) {
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (j === len - 1) {
|
|
43
|
+
if (doc_[piece] !== void 0) {
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (isBeforeSetters != null) {
|
|
48
|
+
if (typeof type.defaultValue === 'function') {
|
|
49
|
+
if (!type.defaultValue.$runBeforeSetters && isBeforeSetters) {
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
if (type.defaultValue.$runBeforeSetters && !isBeforeSetters) {
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
} else if (!isBeforeSetters) {
|
|
56
|
+
// Non-function defaults should always run **before** setters
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (pathsToSkip && pathsToSkip[curPath]) {
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (fields && exclude !== null) {
|
|
66
|
+
if (exclude === true) {
|
|
67
|
+
// apply defaults to all non-excluded fields
|
|
68
|
+
if (p in fields) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
def = type.getDefault(doc, false);
|
|
74
|
+
} catch (err) {
|
|
75
|
+
doc.invalidate(p, err);
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (typeof def !== 'undefined') {
|
|
80
|
+
doc_[piece] = def;
|
|
81
|
+
doc.$__.activePaths.default(p);
|
|
82
|
+
}
|
|
83
|
+
} else if (included) {
|
|
84
|
+
// selected field
|
|
85
|
+
try {
|
|
86
|
+
def = type.getDefault(doc, false);
|
|
87
|
+
} catch (err) {
|
|
88
|
+
doc.invalidate(p, err);
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (typeof def !== 'undefined') {
|
|
93
|
+
doc_[piece] = def;
|
|
94
|
+
doc.$__.activePaths.default(p);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
} else {
|
|
98
|
+
try {
|
|
99
|
+
def = type.getDefault(doc, false);
|
|
100
|
+
} catch (err) {
|
|
101
|
+
doc.invalidate(p, err);
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (typeof def !== 'undefined') {
|
|
106
|
+
doc_[piece] = def;
|
|
107
|
+
doc.$__.activePaths.default(p);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
} else {
|
|
111
|
+
doc_ = doc_[piece];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
};
|
|
@@ -13,7 +13,7 @@ module.exports = function cleanModifiedSubpaths(doc, path, options) {
|
|
|
13
13
|
return deleted;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
for (const modifiedPath of Object.keys(doc.$__.activePaths.
|
|
16
|
+
for (const modifiedPath of Object.keys(doc.$__.activePaths.getStatePaths('modify'))) {
|
|
17
17
|
if (skipDocArrays) {
|
|
18
18
|
const schemaType = doc.$__schema.path(modifiedPath);
|
|
19
19
|
if (schemaType && schemaType.$isMongooseDocumentArray) {
|
|
@@ -21,13 +21,13 @@ module.exports = function cleanModifiedSubpaths(doc, path, options) {
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
if (modifiedPath.startsWith(path + '.')) {
|
|
24
|
-
|
|
24
|
+
doc.$__.activePaths.clearPath(modifiedPath);
|
|
25
25
|
++deleted;
|
|
26
26
|
|
|
27
27
|
if (doc.$isSubdocument) {
|
|
28
28
|
const owner = doc.ownerDocument();
|
|
29
29
|
const fullPath = doc.$__fullPath(modifiedPath);
|
|
30
|
-
|
|
30
|
+
owner.$__.activePaths.clearPath(fullPath);
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
}
|
|
@@ -17,6 +17,13 @@ const isPOJO = utils.isPOJO;
|
|
|
17
17
|
exports.compile = compile;
|
|
18
18
|
exports.defineKey = defineKey;
|
|
19
19
|
|
|
20
|
+
const _isEmptyOptions = Object.freeze({
|
|
21
|
+
minimize: true,
|
|
22
|
+
virtuals: false,
|
|
23
|
+
getters: false,
|
|
24
|
+
transform: false
|
|
25
|
+
});
|
|
26
|
+
|
|
20
27
|
/*!
|
|
21
28
|
* Compiles schemas.
|
|
22
29
|
*/
|
|
@@ -130,12 +137,6 @@ function defineKey({ prop, subprops, prototype, prefix, options }) {
|
|
|
130
137
|
value: true
|
|
131
138
|
});
|
|
132
139
|
|
|
133
|
-
const _isEmptyOptions = Object.freeze({
|
|
134
|
-
minimize: true,
|
|
135
|
-
virtuals: false,
|
|
136
|
-
getters: false,
|
|
137
|
-
transform: false
|
|
138
|
-
});
|
|
139
140
|
Object.defineProperty(nested, '$isEmpty', {
|
|
140
141
|
enumerable: false,
|
|
141
142
|
configurable: true,
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
module.exports = function applyDefaultsToPOJO(doc, schema) {
|
|
4
|
+
const paths = Object.keys(schema.paths);
|
|
5
|
+
const plen = paths.length;
|
|
6
|
+
|
|
7
|
+
for (let i = 0; i < plen; ++i) {
|
|
8
|
+
let curPath = '';
|
|
9
|
+
const p = paths[i];
|
|
10
|
+
|
|
11
|
+
const type = schema.paths[p];
|
|
12
|
+
const path = type.splitPath();
|
|
13
|
+
const len = path.length;
|
|
14
|
+
let doc_ = doc;
|
|
15
|
+
for (let j = 0; j < len; ++j) {
|
|
16
|
+
if (doc_ == null) {
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const piece = path[j];
|
|
21
|
+
curPath += (!curPath.length ? '' : '.') + piece;
|
|
22
|
+
|
|
23
|
+
if (j === len - 1) {
|
|
24
|
+
if (typeof doc_[piece] !== 'undefined') {
|
|
25
|
+
if (type.$isSingleNested) {
|
|
26
|
+
applyDefaultsToPOJO(doc_[piece], type.caster.schema);
|
|
27
|
+
} else if (type.$isMongooseDocumentArray && Array.isArray(doc_[piece])) {
|
|
28
|
+
doc_[piece].forEach(el => applyDefaultsToPOJO(el, type.schema));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const def = type.getDefault(doc, false, { skipCast: true });
|
|
35
|
+
if (typeof def !== 'undefined') {
|
|
36
|
+
doc_[piece] = def;
|
|
37
|
+
|
|
38
|
+
if (type.$isSingleNested) {
|
|
39
|
+
applyDefaultsToPOJO(def, type.caster.schema);
|
|
40
|
+
} else if (type.$isMongooseDocumentArray && Array.isArray(def)) {
|
|
41
|
+
def.forEach(el => applyDefaultsToPOJO(el, type.schema));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
} else {
|
|
45
|
+
if (doc_[piece] == null) {
|
|
46
|
+
doc_[piece] = {};
|
|
47
|
+
}
|
|
48
|
+
doc_ = doc_[piece];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
};
|
|
@@ -20,7 +20,7 @@ module.exports = function castBulkWrite(originalModel, op, options) {
|
|
|
20
20
|
const model = decideModelByObject(originalModel, op['insertOne']['document']);
|
|
21
21
|
|
|
22
22
|
const doc = new model(op['insertOne']['document']);
|
|
23
|
-
if (model.schema.options.timestamps) {
|
|
23
|
+
if (model.schema.options.timestamps && options.timestamps !== false) {
|
|
24
24
|
doc.initializeTimestamps();
|
|
25
25
|
}
|
|
26
26
|
if (options.session != null) {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
module.exports = function pushNestedArrayPaths(paths, nestedArray, path) {
|
|
4
|
+
if (nestedArray == null) {
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
for (let i = 0; i < nestedArray.length; ++i) {
|
|
9
|
+
if (Array.isArray(nestedArray[i])) {
|
|
10
|
+
pushNestedArrayPaths(paths, nestedArray[i], path + '.' + i);
|
|
11
|
+
} else {
|
|
12
|
+
paths.push(path + '.' + i);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
};
|
|
@@ -7,23 +7,32 @@ const emittedSymbol = Symbol('mongoose:emitted');
|
|
|
7
7
|
|
|
8
8
|
module.exports = function promiseOrCallback(callback, fn, ee, Promise) {
|
|
9
9
|
if (typeof callback === 'function') {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if (
|
|
13
|
-
error[emittedSymbol]
|
|
14
|
-
|
|
10
|
+
try {
|
|
11
|
+
return fn(function(error) {
|
|
12
|
+
if (error != null) {
|
|
13
|
+
if (ee != null && ee.listeners != null && ee.listeners('error').length > 0 && !error[emittedSymbol]) {
|
|
14
|
+
error[emittedSymbol] = true;
|
|
15
|
+
ee.emit('error', error);
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
callback(error);
|
|
19
|
+
} catch (error) {
|
|
20
|
+
return immediate(() => {
|
|
21
|
+
throw error;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
return;
|
|
15
25
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
return;
|
|
26
|
+
callback.apply(this, arguments);
|
|
27
|
+
});
|
|
28
|
+
} catch (error) {
|
|
29
|
+
if (ee != null && ee.listeners != null && ee.listeners('error').length > 0 && !error[emittedSymbol]) {
|
|
30
|
+
error[emittedSymbol] = true;
|
|
31
|
+
ee.emit('error', error);
|
|
24
32
|
}
|
|
25
|
-
|
|
26
|
-
|
|
33
|
+
|
|
34
|
+
return callback(error);
|
|
35
|
+
}
|
|
27
36
|
}
|
|
28
37
|
|
|
29
38
|
Promise = Promise || PromiseProvider.get();
|
|
@@ -82,12 +82,15 @@ function applyTimestampsToChildren(now, update, schema) {
|
|
|
82
82
|
function applyTimestampsToDocumentArray(arr, schematype, now) {
|
|
83
83
|
const timestamps = schematype.schema.options.timestamps;
|
|
84
84
|
|
|
85
|
+
const len = arr.length;
|
|
86
|
+
|
|
85
87
|
if (!timestamps) {
|
|
88
|
+
for (let i = 0; i < len; ++i) {
|
|
89
|
+
applyTimestampsToChildren(now, arr[i], schematype.schema);
|
|
90
|
+
}
|
|
86
91
|
return;
|
|
87
92
|
}
|
|
88
93
|
|
|
89
|
-
const len = arr.length;
|
|
90
|
-
|
|
91
94
|
const createdAt = handleTimestampOption(timestamps, 'createdAt');
|
|
92
95
|
const updatedAt = handleTimestampOption(timestamps, 'updatedAt');
|
|
93
96
|
for (let i = 0; i < len; ++i) {
|
|
@@ -105,6 +108,7 @@ function applyTimestampsToDocumentArray(arr, schematype, now) {
|
|
|
105
108
|
function applyTimestampsToSingleNested(subdoc, schematype, now) {
|
|
106
109
|
const timestamps = schematype.schema.options.timestamps;
|
|
107
110
|
if (!timestamps) {
|
|
111
|
+
applyTimestampsToChildren(now, subdoc, schematype.schema);
|
|
108
112
|
return;
|
|
109
113
|
}
|
|
110
114
|
|
package/lib/index.js
CHANGED
|
@@ -51,6 +51,7 @@ const objectIdHexRegexp = /^[0-9A-Fa-f]{24}$/;
|
|
|
51
51
|
* Most apps will only use this one instance.
|
|
52
52
|
*
|
|
53
53
|
* #### Example:
|
|
54
|
+
*
|
|
54
55
|
* const mongoose = require('mongoose');
|
|
55
56
|
* mongoose instanceof mongoose.Mongoose; // true
|
|
56
57
|
*
|
|
@@ -687,7 +688,7 @@ Mongoose.prototype._applyPlugins = function(schema, options) {
|
|
|
687
688
|
* @param {Function} fn plugin callback
|
|
688
689
|
* @param {Object} [opts] optional options
|
|
689
690
|
* @return {Mongoose} this
|
|
690
|
-
* @see plugins
|
|
691
|
+
* @see plugins /docs/plugins
|
|
691
692
|
* @api public
|
|
692
693
|
*/
|
|
693
694
|
|
package/lib/internal.js
CHANGED
|
@@ -13,8 +13,9 @@ function InternalCache() {
|
|
|
13
13
|
this.activePaths = new ActiveRoster();
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
InternalCache.prototype.strictMode = true;
|
|
17
|
+
|
|
16
18
|
InternalCache.prototype.fullPath = undefined;
|
|
17
|
-
InternalCache.prototype.strictMode = undefined;
|
|
18
19
|
InternalCache.prototype.selected = undefined;
|
|
19
20
|
InternalCache.prototype.shardval = undefined;
|
|
20
21
|
InternalCache.prototype.saveError = undefined;
|
|
@@ -28,6 +29,7 @@ InternalCache.prototype._id = undefined;
|
|
|
28
29
|
InternalCache.prototype.ownerDocument = undefined;
|
|
29
30
|
InternalCache.prototype.populate = undefined; // what we want to populate in this doc
|
|
30
31
|
InternalCache.prototype.populated = undefined;// the _ids that have been populated
|
|
32
|
+
InternalCache.prototype.primitiveAtomics = undefined;
|
|
31
33
|
|
|
32
34
|
/**
|
|
33
35
|
* If `false`, this document was not the result of population.
|