mongoose 6.2.8 → 6.2.11
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 +35 -26
- package/CHANGELOG.md +28 -0
- package/dist/browser.umd.js +38 -27
- package/lib/aggregate.js +57 -66
- package/lib/browser.js +4 -4
- package/lib/connection.js +21 -21
- package/lib/cursor/AggregationCursor.js +2 -2
- package/lib/cursor/QueryCursor.js +3 -3
- package/lib/document.js +65 -49
- package/lib/error/index.js +2 -2
- package/lib/helpers/indexes/applySchemaCollation.js +13 -0
- package/lib/helpers/indexes/isTextIndex.js +16 -0
- package/lib/helpers/populate/markArraySubdocsPopulated.js +1 -1
- package/lib/helpers/projection/hasIncludedChildren.js +1 -1
- package/lib/helpers/query/castUpdate.js +3 -1
- package/lib/helpers/update/applyTimestampsToChildren.js +2 -2
- package/lib/helpers/update/applyTimestampsToUpdate.js +0 -1
- package/lib/index.js +24 -26
- package/lib/model.js +144 -146
- package/lib/options/SchemaArrayOptions.js +2 -2
- package/lib/options/SchemaBufferOptions.js +1 -1
- package/lib/options/SchemaDateOptions.js +9 -2
- package/lib/options/SchemaDocumentArrayOptions.js +3 -3
- package/lib/options/SchemaMapOptions.js +2 -2
- package/lib/options/SchemaNumberOptions.js +3 -3
- package/lib/options/SchemaObjectIdOptions.js +2 -2
- package/lib/options/SchemaStringOptions.js +1 -1
- package/lib/options/SchemaSubdocumentOptions.js +2 -2
- package/lib/options/SchemaTypeOptions.js +3 -3
- package/lib/query.js +291 -248
- package/lib/schema/SubdocumentPath.js +4 -3
- package/lib/schema/array.js +2 -2
- package/lib/schema/boolean.js +4 -4
- package/lib/schema/buffer.js +3 -3
- package/lib/schema/date.js +7 -7
- package/lib/schema/decimal128.js +2 -2
- package/lib/schema/documentarray.js +3 -3
- package/lib/schema/mixed.js +2 -2
- package/lib/schema/number.js +6 -6
- package/lib/schema/objectid.js +4 -7
- package/lib/schema/string.js +38 -16
- package/lib/schema.js +30 -29
- package/lib/schematype.js +78 -69
- package/lib/types/ArraySubdocument.js +1 -1
- package/lib/types/DocumentArray/methods/index.js +2 -2
- package/lib/types/array/index.js +1 -1
- package/lib/types/array/methods/index.js +13 -13
- package/lib/types/buffer.js +1 -1
- package/lib/types/decimal128.js +1 -1
- package/lib/types/objectid.js +1 -1
- package/lib/types/subdocument.js +31 -2
- package/lib/virtualtype.js +3 -3
- package/package.json +18 -16
- package/tools/repl.js +8 -8
- package/tools/sharded.js +3 -3
- package/types/aggregate.d.ts +223 -0
- package/types/connection.d.ts +116 -116
- package/types/error.d.ts +2 -2
- package/types/index.d.ts +76 -213
- package/types/pipelinestage.d.ts +194 -194
- package/types/schemaoptions.d.ts +2 -2
|
@@ -112,7 +112,7 @@ QueryCursor.prototype._read = function() {
|
|
|
112
112
|
* Registers a transform function which subsequently maps documents retrieved
|
|
113
113
|
* via the streams interface or `.next()`
|
|
114
114
|
*
|
|
115
|
-
* ####Example
|
|
115
|
+
* #### Example
|
|
116
116
|
*
|
|
117
117
|
* // Map documents returned by `data` events
|
|
118
118
|
* Thing.
|
|
@@ -211,7 +211,7 @@ QueryCursor.prototype.next = function(callback) {
|
|
|
211
211
|
* will wait for the promise to resolve before iterating on to the next one.
|
|
212
212
|
* Returns a promise that resolves when done.
|
|
213
213
|
*
|
|
214
|
-
* ####Example
|
|
214
|
+
* #### Example
|
|
215
215
|
*
|
|
216
216
|
* // Iterate over documents asynchronously
|
|
217
217
|
* Thing.
|
|
@@ -298,7 +298,7 @@ QueryCursor.prototype._transformForAsyncIterator = function() {
|
|
|
298
298
|
* You do not need to call this function explicitly, the JavaScript runtime
|
|
299
299
|
* will call it for you.
|
|
300
300
|
*
|
|
301
|
-
* ####Example
|
|
301
|
+
* #### Example
|
|
302
302
|
*
|
|
303
303
|
* // Works without using `cursor()`
|
|
304
304
|
* for await (const doc of Model.find([{ $sort: { name: 1 } }])) {
|
package/lib/document.js
CHANGED
|
@@ -94,7 +94,7 @@ function Document(obj, fields, skipId, options) {
|
|
|
94
94
|
this.$__ = new InternalCache();
|
|
95
95
|
this.$isNew = 'isNew' in options ? options.isNew : true;
|
|
96
96
|
|
|
97
|
-
if (
|
|
97
|
+
if (options.priorDoc != null) {
|
|
98
98
|
this.$__.priorDoc = options.priorDoc;
|
|
99
99
|
}
|
|
100
100
|
|
|
@@ -119,7 +119,7 @@ function Document(obj, fields, skipId, options) {
|
|
|
119
119
|
fields = undefined;
|
|
120
120
|
} else {
|
|
121
121
|
this.$__.strictMode = schema.options.strict;
|
|
122
|
-
if (fields
|
|
122
|
+
if (fields != null) {
|
|
123
123
|
this.$__.selected = fields;
|
|
124
124
|
}
|
|
125
125
|
}
|
|
@@ -156,9 +156,9 @@ function Document(obj, fields, skipId, options) {
|
|
|
156
156
|
if (obj) {
|
|
157
157
|
// Skip set hooks
|
|
158
158
|
if (this.$__original_set) {
|
|
159
|
-
this.$__original_set(obj, undefined, true);
|
|
159
|
+
this.$__original_set(obj, undefined, true, options);
|
|
160
160
|
} else {
|
|
161
|
-
this.$set(obj, undefined, true);
|
|
161
|
+
this.$set(obj, undefined, true, options);
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
if (obj instanceof Document) {
|
|
@@ -177,8 +177,6 @@ function Document(obj, fields, skipId, options) {
|
|
|
177
177
|
$__applyDefaults(this, fields, exclude, hasIncludedChildren, false, options.skipDefaults);
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
this.$__._id = this._id;
|
|
181
|
-
|
|
182
180
|
if (!this.$__.strictMode && obj) {
|
|
183
181
|
const _this = this;
|
|
184
182
|
const keys = Object.keys(this._doc);
|
|
@@ -268,7 +266,7 @@ Document.prototype.schema;
|
|
|
268
266
|
* is handy for passing data to middleware without conflicting with Mongoose
|
|
269
267
|
* internals.
|
|
270
268
|
*
|
|
271
|
-
* ####Example:
|
|
269
|
+
* #### Example:
|
|
272
270
|
*
|
|
273
271
|
* schema.pre('save', function() {
|
|
274
272
|
* // Mongoose will set `isNew` to `false` if `save()` succeeds
|
|
@@ -326,7 +324,7 @@ Document.prototype.isNew;
|
|
|
326
324
|
/**
|
|
327
325
|
* Set this property to add additional query filters when Mongoose saves this document and `isNew` is false.
|
|
328
326
|
*
|
|
329
|
-
* ####Example:
|
|
327
|
+
* #### Example:
|
|
330
328
|
*
|
|
331
329
|
* // Make sure `save()` never updates a soft deleted document.
|
|
332
330
|
* schema.pre('save', function() {
|
|
@@ -348,7 +346,7 @@ Object.defineProperty(Document.prototype, '$where', {
|
|
|
348
346
|
/**
|
|
349
347
|
* The string version of this documents _id.
|
|
350
348
|
*
|
|
351
|
-
* ####Note:
|
|
349
|
+
* #### Note:
|
|
352
350
|
*
|
|
353
351
|
* This getter exists on all documents by default. The getter can be disabled by setting the `id` [option](/docs/guide.html#id) of its `Schema` to false at construction time.
|
|
354
352
|
*
|
|
@@ -389,7 +387,7 @@ Document.prototype.errors;
|
|
|
389
387
|
* A string containing the current operation that Mongoose is executing
|
|
390
388
|
* on this document. May be `null`, `'save'`, `'validate'`, or `'remove'`.
|
|
391
389
|
*
|
|
392
|
-
* ####Example:
|
|
390
|
+
* #### Example:
|
|
393
391
|
*
|
|
394
392
|
* const doc = new Model({ name: 'test' });
|
|
395
393
|
* doc.$op; // null
|
|
@@ -743,8 +741,6 @@ Document.prototype.$__init = function(doc, opts) {
|
|
|
743
741
|
this.$emit('init', this);
|
|
744
742
|
this.constructor.emit('init', this);
|
|
745
743
|
|
|
746
|
-
this.$__._id = this._id;
|
|
747
|
-
|
|
748
744
|
const hasIncludedChildren = this.$__.exclude === false && this.$__.fields ?
|
|
749
745
|
$__hasIncludedChildren(this.$__.fields) :
|
|
750
746
|
null;
|
|
@@ -841,11 +837,11 @@ function init(self, obj, doc, opts, prefix) {
|
|
|
841
837
|
/**
|
|
842
838
|
* Sends an update command with this document `_id` as the query selector.
|
|
843
839
|
*
|
|
844
|
-
* ####Example:
|
|
840
|
+
* #### Example:
|
|
845
841
|
*
|
|
846
842
|
* weirdCar.update({$inc: {wheels:1}}, { w: 1 }, callback);
|
|
847
843
|
*
|
|
848
|
-
* ####Valid options:
|
|
844
|
+
* #### Valid options:
|
|
849
845
|
*
|
|
850
846
|
* - same as in [Model.update](#model_Model.update)
|
|
851
847
|
*
|
|
@@ -876,11 +872,11 @@ Document.prototype.update = function update() {
|
|
|
876
872
|
/**
|
|
877
873
|
* Sends an updateOne command with this document `_id` as the query selector.
|
|
878
874
|
*
|
|
879
|
-
* ####Example:
|
|
875
|
+
* #### Example:
|
|
880
876
|
*
|
|
881
877
|
* weirdCar.updateOne({$inc: {wheels:1}}, { w: 1 }, callback);
|
|
882
878
|
*
|
|
883
|
-
* ####Valid options:
|
|
879
|
+
* #### Valid options:
|
|
884
880
|
*
|
|
885
881
|
* - same as in [Model.updateOne](#model_Model.updateOne)
|
|
886
882
|
*
|
|
@@ -922,7 +918,7 @@ Document.prototype.updateOne = function updateOne(doc, options, callback) {
|
|
|
922
918
|
/**
|
|
923
919
|
* Sends a replaceOne command with this document `_id` as the query selector.
|
|
924
920
|
*
|
|
925
|
-
* ####Valid options:
|
|
921
|
+
* #### Valid options:
|
|
926
922
|
*
|
|
927
923
|
* - same as in [Model.replaceOne](https://mongoosejs.com/docs/api/model.html#model_Model.replaceOne)
|
|
928
924
|
*
|
|
@@ -947,7 +943,7 @@ Document.prototype.replaceOne = function replaceOne() {
|
|
|
947
943
|
* automatically set `session` if you `save()` a doc that you got from a
|
|
948
944
|
* query with an associated session.
|
|
949
945
|
*
|
|
950
|
-
* ####Example:
|
|
946
|
+
* #### Example:
|
|
951
947
|
*
|
|
952
948
|
* const session = MyModel.startSession();
|
|
953
949
|
* const doc = await MyModel.findOne().session(session);
|
|
@@ -1514,7 +1510,7 @@ function _isManuallyPopulatedArray(val, ref) {
|
|
|
1514
1510
|
/**
|
|
1515
1511
|
* Sets the value of a path, or many paths.
|
|
1516
1512
|
*
|
|
1517
|
-
* ####Example:
|
|
1513
|
+
* #### Example:
|
|
1518
1514
|
*
|
|
1519
1515
|
* // path, value
|
|
1520
1516
|
* doc.set(path, value)
|
|
@@ -1718,7 +1714,7 @@ Document.prototype.$__setValue = function(path, val) {
|
|
|
1718
1714
|
/**
|
|
1719
1715
|
* Returns the value of a path.
|
|
1720
1716
|
*
|
|
1721
|
-
* ####Example
|
|
1717
|
+
* #### Example
|
|
1722
1718
|
*
|
|
1723
1719
|
* // path
|
|
1724
1720
|
* doc.get('age') // 47
|
|
@@ -1824,7 +1820,7 @@ Document.prototype.$__path = function(path) {
|
|
|
1824
1820
|
*
|
|
1825
1821
|
* _Very helpful when using [Mixed](https://mongoosejs.com/docs/schematypes.html#mixed) types._
|
|
1826
1822
|
*
|
|
1827
|
-
* ####Example:
|
|
1823
|
+
* #### Example:
|
|
1828
1824
|
*
|
|
1829
1825
|
* doc.mixed.type = 'changed';
|
|
1830
1826
|
* doc.markModified('mixed.type');
|
|
@@ -1836,6 +1832,7 @@ Document.prototype.$__path = function(path) {
|
|
|
1836
1832
|
*/
|
|
1837
1833
|
|
|
1838
1834
|
Document.prototype.markModified = function(path, scope) {
|
|
1835
|
+
// console.log('MarkModified', path, new Error().stack);
|
|
1839
1836
|
this.$__.activePaths.modify(path);
|
|
1840
1837
|
if (scope != null && !this.$isSubdocument) {
|
|
1841
1838
|
this.$__.pathsToScopes = this.$__pathsToScopes || {};
|
|
@@ -1846,7 +1843,7 @@ Document.prototype.markModified = function(path, scope) {
|
|
|
1846
1843
|
/**
|
|
1847
1844
|
* Clears the modified state on the specified path.
|
|
1848
1845
|
*
|
|
1849
|
-
* ####Example:
|
|
1846
|
+
* #### Example:
|
|
1850
1847
|
*
|
|
1851
1848
|
* doc.foo = 'bar';
|
|
1852
1849
|
* doc.unmarkModified('foo');
|
|
@@ -1866,7 +1863,7 @@ Document.prototype.unmarkModified = function(path) {
|
|
|
1866
1863
|
/**
|
|
1867
1864
|
* Don't run validation on this path or persist changes to this path.
|
|
1868
1865
|
*
|
|
1869
|
-
* ####Example:
|
|
1866
|
+
* #### Example:
|
|
1870
1867
|
*
|
|
1871
1868
|
* doc.foo = null;
|
|
1872
1869
|
* doc.$ignore('foo');
|
|
@@ -1891,7 +1888,7 @@ Document.prototype.$ignore = function(path) {
|
|
|
1891
1888
|
* A path `a` may be in `modifiedPaths()` but not in `directModifiedPaths()`
|
|
1892
1889
|
* because a child of `a` was directly modified.
|
|
1893
1890
|
*
|
|
1894
|
-
* ####Example
|
|
1891
|
+
* #### Example
|
|
1895
1892
|
* const schema = new Schema({ foo: String, nested: { bar: String } });
|
|
1896
1893
|
* const Model = mongoose.model('Test', schema);
|
|
1897
1894
|
* await Model.create({ foo: 'original', nested: { bar: 'original' } });
|
|
@@ -1914,7 +1911,7 @@ Document.prototype.directModifiedPaths = function() {
|
|
|
1914
1911
|
* Useful for determining whether this subdoc will get stripped out by the
|
|
1915
1912
|
* [minimize option](/docs/guide.html#minimize).
|
|
1916
1913
|
*
|
|
1917
|
-
* ####Example:
|
|
1914
|
+
* #### Example:
|
|
1918
1915
|
* const schema = new Schema({ nested: { foo: String } });
|
|
1919
1916
|
* const Model = mongoose.model('Test', schema);
|
|
1920
1917
|
* const doc = new Model({});
|
|
@@ -2047,7 +2044,7 @@ Document.prototype[documentModifiedPaths] = Document.prototype.modifiedPaths;
|
|
|
2047
2044
|
*
|
|
2048
2045
|
* If `path` is given, checks if a path or any full path containing `path` as part of its path chain has been modified.
|
|
2049
2046
|
*
|
|
2050
|
-
* ####Example
|
|
2047
|
+
* #### Example
|
|
2051
2048
|
*
|
|
2052
2049
|
* doc.set('documents.0.title', 'changed');
|
|
2053
2050
|
* doc.isModified() // true
|
|
@@ -2093,7 +2090,7 @@ Document.prototype[documentIsModified] = Document.prototype.isModified;
|
|
|
2093
2090
|
/**
|
|
2094
2091
|
* Checks if a path is set to its default.
|
|
2095
2092
|
*
|
|
2096
|
-
* ####Example
|
|
2093
|
+
* #### Example
|
|
2097
2094
|
*
|
|
2098
2095
|
* MyModel = mongoose.model('test', { name: { type: String, default: 'Val '} });
|
|
2099
2096
|
* const m = new MyModel();
|
|
@@ -2127,7 +2124,7 @@ Document.prototype.$isDefault = function(path) {
|
|
|
2127
2124
|
/**
|
|
2128
2125
|
* Getter/setter, determines whether the document was removed or not.
|
|
2129
2126
|
*
|
|
2130
|
-
* ####Example:
|
|
2127
|
+
* #### Example:
|
|
2131
2128
|
* const product = await product.remove();
|
|
2132
2129
|
* product.$isDeleted(); // true
|
|
2133
2130
|
* product.remove(); // no-op, doesn't send anything to the db
|
|
@@ -2157,7 +2154,7 @@ Document.prototype.$isDeleted = function(val) {
|
|
|
2157
2154
|
/**
|
|
2158
2155
|
* Returns true if `path` was directly set and modified, else false.
|
|
2159
2156
|
*
|
|
2160
|
-
* ####Example
|
|
2157
|
+
* #### Example
|
|
2161
2158
|
*
|
|
2162
2159
|
* doc.set('documents.0.title', 'changed');
|
|
2163
2160
|
* doc.isDirectModified('documents.0.title') // true
|
|
@@ -2213,7 +2210,7 @@ Document.prototype.isInit = function(path) {
|
|
|
2213
2210
|
/**
|
|
2214
2211
|
* Checks if `path` was selected in the source query which initialized this document.
|
|
2215
2212
|
*
|
|
2216
|
-
* ####Example
|
|
2213
|
+
* #### Example
|
|
2217
2214
|
*
|
|
2218
2215
|
* const doc = await Thing.findOne().select('name');
|
|
2219
2216
|
* doc.isSelected('name') // true
|
|
@@ -2294,7 +2291,7 @@ Document.prototype.$__isSelected = Document.prototype.isSelected;
|
|
|
2294
2291
|
* Checks if `path` was explicitly selected. If no projection, always returns
|
|
2295
2292
|
* true.
|
|
2296
2293
|
*
|
|
2297
|
-
* ####Example
|
|
2294
|
+
* #### Example
|
|
2298
2295
|
*
|
|
2299
2296
|
* Thing.findOne().select('nested.name').exec(function (err, doc) {
|
|
2300
2297
|
* doc.isDirectSelected('nested.name') // true
|
|
@@ -2356,11 +2353,11 @@ Document.prototype.isDirectSelected = function isDirectSelected(path) {
|
|
|
2356
2353
|
/**
|
|
2357
2354
|
* Executes registered validation rules for this document.
|
|
2358
2355
|
*
|
|
2359
|
-
* ####Note:
|
|
2356
|
+
* #### Note:
|
|
2360
2357
|
*
|
|
2361
2358
|
* This method is called `pre` save and if a validation rule is violated, [save](#model_Model-save) is aborted and the error is returned to your `callback`.
|
|
2362
2359
|
*
|
|
2363
|
-
* ####Example:
|
|
2360
|
+
* #### Example:
|
|
2364
2361
|
*
|
|
2365
2362
|
* doc.validate(function (err) {
|
|
2366
2363
|
* if (err) handleError(err);
|
|
@@ -2422,6 +2419,7 @@ Document.prototype.validate = function(pathsToValidate, options, callback) {
|
|
|
2422
2419
|
|
|
2423
2420
|
this.$__validate(pathsToValidate, options, (error) => {
|
|
2424
2421
|
this.$op = null;
|
|
2422
|
+
this.$__.validating = null;
|
|
2425
2423
|
cb(error);
|
|
2426
2424
|
});
|
|
2427
2425
|
}, this.constructor.events);
|
|
@@ -2483,10 +2481,7 @@ function _getPathsToValidate(doc) {
|
|
|
2483
2481
|
if (subdoc.$basePath) {
|
|
2484
2482
|
// Remove child paths for now, because we'll be validating the whole
|
|
2485
2483
|
// subdoc
|
|
2486
|
-
|
|
2487
|
-
subdoc.ownerDocument();
|
|
2488
|
-
}
|
|
2489
|
-
const fullPathToSubdoc = subdoc.$__.fullPath;
|
|
2484
|
+
const fullPathToSubdoc = subdoc.$__fullPathWithIndexes();
|
|
2490
2485
|
|
|
2491
2486
|
for (const p of paths) {
|
|
2492
2487
|
if (p === null || p.startsWith(fullPathToSubdoc + '.')) {
|
|
@@ -2504,12 +2499,32 @@ function _getPathsToValidate(doc) {
|
|
|
2504
2499
|
}
|
|
2505
2500
|
}
|
|
2506
2501
|
|
|
2502
|
+
for (const path of paths) {
|
|
2503
|
+
const _pathType = doc.$__schema.path(path);
|
|
2504
|
+
if (!_pathType) {
|
|
2505
|
+
continue;
|
|
2506
|
+
}
|
|
2507
|
+
|
|
2508
|
+
// Optimization: if primitive path with no validators, or array of primitives
|
|
2509
|
+
// with no validators, skip validating this path entirely.
|
|
2510
|
+
if (!_pathType.caster && _pathType.validators.length === 0) {
|
|
2511
|
+
paths.delete(path);
|
|
2512
|
+
} else if (_pathType.$isMongooseArray &&
|
|
2513
|
+
!_pathType.$isMongooseDocumentArray && // Skip document arrays...
|
|
2514
|
+
!_pathType.$embeddedSchemaType.$isMongooseArray && // and arrays of arrays
|
|
2515
|
+
_pathType.validators.length === 0 && // and arrays with top-level validators
|
|
2516
|
+
_pathType.$embeddedSchemaType.validators.length === 0) {
|
|
2517
|
+
paths.delete(path);
|
|
2518
|
+
}
|
|
2519
|
+
}
|
|
2520
|
+
|
|
2507
2521
|
// from here on we're not removing items from paths
|
|
2508
2522
|
|
|
2509
2523
|
// gh-661: if a whole array is modified, make sure to run validation on all
|
|
2510
2524
|
// the children as well
|
|
2511
2525
|
for (const path of paths) {
|
|
2512
2526
|
const _pathType = doc.$__schema.path(path);
|
|
2527
|
+
|
|
2513
2528
|
if (!_pathType ||
|
|
2514
2529
|
!_pathType.$isMongooseArray ||
|
|
2515
2530
|
// To avoid potential performance issues, skip doc arrays whose children
|
|
@@ -2616,7 +2631,8 @@ Document.prototype.$__validate = function(pathsToValidate, options, callback) {
|
|
|
2616
2631
|
const _this = this;
|
|
2617
2632
|
const _complete = () => {
|
|
2618
2633
|
let validationError = this.$__.validationError;
|
|
2619
|
-
this.$__.validationError =
|
|
2634
|
+
this.$__.validationError = null;
|
|
2635
|
+
this.$__.validating = null;
|
|
2620
2636
|
|
|
2621
2637
|
if (shouldValidateModifiedOnly && validationError != null) {
|
|
2622
2638
|
// Remove any validation errors that aren't from modified paths
|
|
@@ -2803,11 +2819,11 @@ function _handlePathsToSkip(paths, pathsToSkip) {
|
|
|
2803
2819
|
/**
|
|
2804
2820
|
* Executes registered validation rules (skipping asynchronous validators) for this document.
|
|
2805
2821
|
*
|
|
2806
|
-
* ####Note:
|
|
2822
|
+
* #### Note:
|
|
2807
2823
|
*
|
|
2808
2824
|
* This method is useful if you need synchronous validation.
|
|
2809
2825
|
*
|
|
2810
|
-
* ####Example:
|
|
2826
|
+
* #### Example:
|
|
2811
2827
|
*
|
|
2812
2828
|
* const err = doc.validateSync();
|
|
2813
2829
|
* if (err) {
|
|
@@ -3042,7 +3058,7 @@ function _checkImmutableSubpaths(subdoc, schematype, priorVal) {
|
|
|
3042
3058
|
* Saves this document by inserting a new document into the database if [document.isNew](/docs/api.html#document_Document-isNew) is `true`,
|
|
3043
3059
|
* or sends an [updateOne](/docs/api.html#document_Document-updateOne) operation **only** with the modifications to the database, it does not replace the whole document in the latter case.
|
|
3044
3060
|
*
|
|
3045
|
-
* ####Example:
|
|
3061
|
+
* #### Example:
|
|
3046
3062
|
*
|
|
3047
3063
|
* product.sold = Date.now();
|
|
3048
3064
|
* product = await product.save();
|
|
@@ -3050,7 +3066,7 @@ function _checkImmutableSubpaths(subdoc, schematype, priorVal) {
|
|
|
3050
3066
|
* If save is successful, the returned promise will fulfill with the document
|
|
3051
3067
|
* saved.
|
|
3052
3068
|
*
|
|
3053
|
-
* ####Example:
|
|
3069
|
+
* #### Example:
|
|
3054
3070
|
*
|
|
3055
3071
|
* const newProduct = await product.save();
|
|
3056
3072
|
* newProduct === product; // true
|
|
@@ -3578,7 +3594,7 @@ Document.prototype.$toObject = function(options, json) {
|
|
|
3578
3594
|
*
|
|
3579
3595
|
* Buffers are converted to instances of [mongodb.Binary](https://mongodb.github.com/node-mongodb-native/api-bson-generated/binary.html) for proper storage.
|
|
3580
3596
|
*
|
|
3581
|
-
* ####Options:
|
|
3597
|
+
* #### Options:
|
|
3582
3598
|
*
|
|
3583
3599
|
* - `getters` apply all getters (path and virtual getters), defaults to false
|
|
3584
3600
|
* - `aliases` apply all aliases if `virtuals=true`, defaults to true
|
|
@@ -3590,7 +3606,7 @@ Document.prototype.$toObject = function(options, json) {
|
|
|
3590
3606
|
* - `flattenMaps` convert Maps to POJOs. Useful if you want to JSON.stringify() the result of toObject(), defaults to false
|
|
3591
3607
|
* - `useProjection` set to `true` to omit fields that are excluded in this document's projection. Unless you specified a projection, this will omit any field that has `select: false` in the schema.
|
|
3592
3608
|
*
|
|
3593
|
-
* ####Getters/Virtuals
|
|
3609
|
+
* #### Getters/Virtuals
|
|
3594
3610
|
*
|
|
3595
3611
|
* Example of only applying path getters
|
|
3596
3612
|
*
|
|
@@ -3608,7 +3624,7 @@ Document.prototype.$toObject = function(options, json) {
|
|
|
3608
3624
|
*
|
|
3609
3625
|
* schema.set('toObject', { virtuals: true })
|
|
3610
3626
|
*
|
|
3611
|
-
* ####Transform
|
|
3627
|
+
* #### Transform
|
|
3612
3628
|
*
|
|
3613
3629
|
* We may need to perform a transformation of the resulting object based on some criteria, say to remove some sensitive information or return a custom object. In this case we set the optional `transform` function.
|
|
3614
3630
|
*
|
|
@@ -3620,7 +3636,7 @@ Document.prototype.$toObject = function(options, json) {
|
|
|
3620
3636
|
* - `ret` The plain object representation which has been converted
|
|
3621
3637
|
* - `options` The options in use (either schema options or the options passed inline)
|
|
3622
3638
|
*
|
|
3623
|
-
* ####Example
|
|
3639
|
+
* #### Example
|
|
3624
3640
|
*
|
|
3625
3641
|
* // specify the transform schema option
|
|
3626
3642
|
* if (!schema.options.toObject) schema.options.toObject = {};
|
|
@@ -4114,7 +4130,7 @@ Document.prototype.equals = function(doc) {
|
|
|
4114
4130
|
/**
|
|
4115
4131
|
* Populates paths on an existing document.
|
|
4116
4132
|
*
|
|
4117
|
-
* ####Example:
|
|
4133
|
+
* #### Example:
|
|
4118
4134
|
*
|
|
4119
4135
|
* await doc.populate([
|
|
4120
4136
|
* 'stories',
|
|
@@ -4231,7 +4247,7 @@ Document.prototype.$getPopulatedDocs = function $getPopulatedDocs() {
|
|
|
4231
4247
|
/**
|
|
4232
4248
|
* Gets _id(s) used during population of the given `path`.
|
|
4233
4249
|
*
|
|
4234
|
-
* ####Example:
|
|
4250
|
+
* #### Example:
|
|
4235
4251
|
*
|
|
4236
4252
|
* Model.findOne().populate('author').exec(function (err, doc) {
|
|
4237
4253
|
* console.log(doc.author.name) // Dr.Seuss
|
|
@@ -4293,7 +4309,7 @@ Document.prototype.$populated = Document.prototype.populated;
|
|
|
4293
4309
|
/**
|
|
4294
4310
|
* Takes a populated field and returns it to its unpopulated state.
|
|
4295
4311
|
*
|
|
4296
|
-
* ####Example:
|
|
4312
|
+
* #### Example:
|
|
4297
4313
|
*
|
|
4298
4314
|
* Model.findOne().populate('author').exec(function (err, doc) {
|
|
4299
4315
|
* console.log(doc.author.name); // Dr.Seuss
|
package/lib/error/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* MongooseError constructor. MongooseError is the base class for all
|
|
5
5
|
* Mongoose-specific errors.
|
|
6
6
|
*
|
|
7
|
-
* ####Example:
|
|
7
|
+
* #### Example:
|
|
8
8
|
* const Model = mongoose.model('Test', new Schema({ answer: Number }));
|
|
9
9
|
* const doc = new Model({ answer: 'not a number' });
|
|
10
10
|
* const err = doc.validateSync();
|
|
@@ -105,7 +105,7 @@ MongooseError.ValidationError = require('./validation');
|
|
|
105
105
|
* A `ValidationError` has a hash of `errors` that contain individual
|
|
106
106
|
* `ValidatorError` instances.
|
|
107
107
|
*
|
|
108
|
-
* ####Example:
|
|
108
|
+
* #### Example:
|
|
109
109
|
*
|
|
110
110
|
* const schema = Schema({ name: { type: String, required: true } });
|
|
111
111
|
* const Model = mongoose.model('Test', schema);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const isTextIndex = require('./isTextIndex');
|
|
4
|
+
|
|
5
|
+
module.exports = function applySchemaCollation(indexKeys, indexOptions, schemaOptions) {
|
|
6
|
+
if (isTextIndex(indexKeys)) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (schemaOptions.hasOwnProperty('collation') && !indexOptions.hasOwnProperty('collation')) {
|
|
11
|
+
indexOptions.collation = schemaOptions.collation;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns `true` if the given index options have a `text` option.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
module.exports = function isTextIndex(indexKeys) {
|
|
8
|
+
let isTextIndex = false;
|
|
9
|
+
for (const key of Object.keys(indexKeys)) {
|
|
10
|
+
if (indexKeys[key] === 'text') {
|
|
11
|
+
isTextIndex = true;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return isTextIndex;
|
|
16
|
+
};
|
|
@@ -6,7 +6,7 @@ const utils = require('../../utils');
|
|
|
6
6
|
* If populating a path within a document array, make sure each
|
|
7
7
|
* subdoc within the array knows its subpaths are populated.
|
|
8
8
|
*
|
|
9
|
-
* ####Example:
|
|
9
|
+
* #### Example:
|
|
10
10
|
* const doc = await Article.findOne().populate('comments.author');
|
|
11
11
|
* doc.comments[0].populated('author'); // Should be set
|
|
12
12
|
*/
|
|
@@ -47,7 +47,7 @@ module.exports = function castUpdate(schema, obj, options, context, filter) {
|
|
|
47
47
|
} else if (!options.overwriteDiscriminatorKey) {
|
|
48
48
|
delete obj[schema.options.discriminatorKey];
|
|
49
49
|
}
|
|
50
|
-
if (options.upsert) {
|
|
50
|
+
if (options.upsert && !options.overwrite) {
|
|
51
51
|
moveImmutableProperties(schema, obj, context);
|
|
52
52
|
}
|
|
53
53
|
|
|
@@ -217,6 +217,7 @@ function walkUpdatePath(schema, obj, op, options, context, filter, pref) {
|
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
if (op !== '$setOnInsert' &&
|
|
220
|
+
!options.overwrite &&
|
|
220
221
|
handleImmutable(schematype, strict, obj, key, prefix + key, context)) {
|
|
221
222
|
continue;
|
|
222
223
|
}
|
|
@@ -311,6 +312,7 @@ function walkUpdatePath(schema, obj, op, options, context, filter, pref) {
|
|
|
311
312
|
|
|
312
313
|
// You can use `$setOnInsert` with immutable keys
|
|
313
314
|
if (op !== '$setOnInsert' &&
|
|
315
|
+
!options.overwrite &&
|
|
314
316
|
handleImmutable(schematype, strict, obj, key, prefix + key, context)) {
|
|
315
317
|
continue;
|
|
316
318
|
}
|
|
@@ -15,7 +15,7 @@ function applyTimestampsToChildren(now, update, schema) {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
const keys = Object.keys(update);
|
|
18
|
-
const hasDollarKey = keys.some(key => key
|
|
18
|
+
const hasDollarKey = keys.some(key => key[0] === '$');
|
|
19
19
|
|
|
20
20
|
if (hasDollarKey) {
|
|
21
21
|
if (update.$push) {
|
|
@@ -38,7 +38,7 @@ function applyTimestampsToChildren(now, update, schema) {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
const updateKeys = Object.keys(update).filter(key =>
|
|
41
|
+
const updateKeys = Object.keys(update).filter(key => key[0] !== '$');
|
|
42
42
|
for (const key of updateKeys) {
|
|
43
43
|
applyTimestampsToUpdateKey(schema, key, update, now);
|
|
44
44
|
}
|