mongoose 7.0.1 → 7.0.3
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.js +232 -0
- package/README.md +15 -15
- package/dist/browser.umd.js +1 -1
- package/lib/aggregate.js +1 -1
- package/lib/connection.js +10 -0
- package/lib/cursor/AggregationCursor.js +1 -1
- package/lib/cursor/QueryCursor.js +1 -1
- package/lib/document.js +41 -35
- package/lib/helpers/document/applyDefaults.js +1 -1
- package/lib/helpers/timestamps/setupTimestamps.js +6 -1
- package/lib/model.js +36 -14
- package/lib/query.js +7 -6
- package/lib/schema/documentarray.js +5 -3
- package/lib/schema.js +16 -5
- package/package.json +5 -2
- package/scripts/generateSearch.js +31 -24
- package/scripts/loadSponsorData.js +115 -0
- package/types/cursor.d.ts +2 -2
- package/types/models.d.ts +18 -0
- package/types/query.d.ts +3 -3
- package/types/types.d.ts +1 -1
- package/.eslintrc.json +0 -195
package/lib/aggregate.js
CHANGED
|
@@ -1127,7 +1127,7 @@ Aggregate.prototype.catch = function(reject) {
|
|
|
1127
1127
|
* `Symbol.asyncIterator` is undefined, that means your Node.js version does not
|
|
1128
1128
|
* support async iterators.
|
|
1129
1129
|
*
|
|
1130
|
-
* @method Symbol.asyncIterator
|
|
1130
|
+
* @method [Symbol.asyncIterator]
|
|
1131
1131
|
* @memberOf Aggregate
|
|
1132
1132
|
* @instance
|
|
1133
1133
|
* @api public
|
package/lib/connection.js
CHANGED
|
@@ -1057,6 +1057,16 @@ Connection.prototype._close = async function _close(force, destroy) {
|
|
|
1057
1057
|
return this;
|
|
1058
1058
|
};
|
|
1059
1059
|
|
|
1060
|
+
/**
|
|
1061
|
+
* Abstract method that drivers must implement.
|
|
1062
|
+
*
|
|
1063
|
+
* @api private
|
|
1064
|
+
*/
|
|
1065
|
+
|
|
1066
|
+
Connection.prototype.doClose = function() {
|
|
1067
|
+
throw new Error('Connection#doClose unimplemented by driver');
|
|
1068
|
+
};
|
|
1069
|
+
|
|
1060
1070
|
/**
|
|
1061
1071
|
* Called when the connection closes
|
|
1062
1072
|
*
|
|
@@ -263,7 +263,7 @@ AggregationCursor.prototype.eachAsync = function(fn, opts, callback) {
|
|
|
263
263
|
* `Symbol.asyncIterator` is undefined, that means your Node.js version does not
|
|
264
264
|
* support async iterators.
|
|
265
265
|
*
|
|
266
|
-
* @method Symbol.asyncIterator
|
|
266
|
+
* @method [Symbol.asyncIterator]
|
|
267
267
|
* @memberOf AggregationCursor
|
|
268
268
|
* @instance
|
|
269
269
|
* @api public
|
|
@@ -347,7 +347,7 @@ QueryCursor.prototype._transformForAsyncIterator = function() {
|
|
|
347
347
|
* `Symbol.asyncIterator` is undefined, that means your Node.js version does not
|
|
348
348
|
* support async iterators.
|
|
349
349
|
*
|
|
350
|
-
* @method Symbol.asyncIterator
|
|
350
|
+
* @method [Symbol.asyncIterator]
|
|
351
351
|
* @memberOf QueryCursor
|
|
352
352
|
* @instance
|
|
353
353
|
* @api public
|
package/lib/document.js
CHANGED
|
@@ -17,7 +17,6 @@ const ValidationError = require('./error/validation');
|
|
|
17
17
|
const ValidatorError = require('./error/validator');
|
|
18
18
|
const VirtualType = require('./virtualtype');
|
|
19
19
|
const $__hasIncludedChildren = require('./helpers/projection/hasIncludedChildren');
|
|
20
|
-
const castNumber = require('./cast/number');
|
|
21
20
|
const applyDefaults = require('./helpers/document/applyDefaults');
|
|
22
21
|
const cleanModifiedSubpaths = require('./helpers/document/cleanModifiedSubpaths');
|
|
23
22
|
const clone = require('./helpers/clone');
|
|
@@ -1747,18 +1746,26 @@ Document.prototype.$inc = function $inc(path, val) {
|
|
|
1747
1746
|
return this;
|
|
1748
1747
|
}
|
|
1749
1748
|
|
|
1749
|
+
const currentValue = this.$__getValue(path) || 0;
|
|
1750
|
+
let shouldSet = false;
|
|
1751
|
+
let valToSet = null;
|
|
1752
|
+
let valToInc = val;
|
|
1753
|
+
|
|
1750
1754
|
try {
|
|
1751
|
-
val =
|
|
1755
|
+
val = schemaType.cast(val);
|
|
1756
|
+
valToSet = schemaType.applySetters(currentValue + val, this);
|
|
1757
|
+
valToInc = valToSet - currentValue;
|
|
1758
|
+
shouldSet = true;
|
|
1752
1759
|
} catch (err) {
|
|
1753
1760
|
this.invalidate(path, new MongooseError.CastError('number', val, path, err));
|
|
1754
1761
|
}
|
|
1755
1762
|
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1763
|
+
if (shouldSet) {
|
|
1764
|
+
this.$__.primitiveAtomics = this.$__.primitiveAtomics || {};
|
|
1765
|
+
this.$__.primitiveAtomics[path] = { $inc: valToInc };
|
|
1766
|
+
this.markModified(path);
|
|
1767
|
+
this.$__setValue(path, valToSet);
|
|
1768
|
+
}
|
|
1762
1769
|
|
|
1763
1770
|
return this;
|
|
1764
1771
|
};
|
|
@@ -2557,7 +2564,7 @@ function _evaluateRequiredFunctions(doc) {
|
|
|
2557
2564
|
* ignore
|
|
2558
2565
|
*/
|
|
2559
2566
|
|
|
2560
|
-
function _getPathsToValidate(doc) {
|
|
2567
|
+
function _getPathsToValidate(doc, pathsToValidate, pathsToSkip) {
|
|
2561
2568
|
const skipSchemaValidators = {};
|
|
2562
2569
|
|
|
2563
2570
|
_evaluateRequiredFunctions(doc);
|
|
@@ -2628,6 +2635,22 @@ function _getPathsToValidate(doc) {
|
|
|
2628
2635
|
}
|
|
2629
2636
|
}
|
|
2630
2637
|
|
|
2638
|
+
for (const path of paths) {
|
|
2639
|
+
// Single nested paths (paths embedded under single nested subdocs) will
|
|
2640
|
+
// be validated on their own when we call `validate()` on the subdoc itself.
|
|
2641
|
+
// Re: gh-8468
|
|
2642
|
+
if (doc.$__schema.singleNestedPaths.hasOwnProperty(path)) {
|
|
2643
|
+
paths.delete(path);
|
|
2644
|
+
continue;
|
|
2645
|
+
}
|
|
2646
|
+
}
|
|
2647
|
+
|
|
2648
|
+
if (Array.isArray(pathsToValidate)) {
|
|
2649
|
+
paths = _handlePathsToValidate(paths, pathsToValidate);
|
|
2650
|
+
} else if (Array.isArray(pathsToSkip)) {
|
|
2651
|
+
paths = _handlePathsToSkip(paths, pathsToSkip);
|
|
2652
|
+
}
|
|
2653
|
+
|
|
2631
2654
|
// from here on we're not removing items from paths
|
|
2632
2655
|
|
|
2633
2656
|
// gh-661: if a whole array is modified, make sure to run validation on all
|
|
@@ -2687,13 +2710,6 @@ function _getPathsToValidate(doc) {
|
|
|
2687
2710
|
}
|
|
2688
2711
|
|
|
2689
2712
|
for (const path of paths) {
|
|
2690
|
-
// Single nested paths (paths embedded under single nested subdocs) will
|
|
2691
|
-
// be validated on their own when we call `validate()` on the subdoc itself.
|
|
2692
|
-
// Re: gh-8468
|
|
2693
|
-
if (doc.$__schema.singleNestedPaths.hasOwnProperty(path)) {
|
|
2694
|
-
paths.delete(path);
|
|
2695
|
-
continue;
|
|
2696
|
-
}
|
|
2697
2713
|
const _pathType = doc.$__schema.path(path);
|
|
2698
2714
|
if (!_pathType || !_pathType.$isSchemaMap) {
|
|
2699
2715
|
continue;
|
|
@@ -2776,19 +2792,14 @@ Document.prototype.$__validate = function(pathsToValidate, options, callback) {
|
|
|
2776
2792
|
};
|
|
2777
2793
|
|
|
2778
2794
|
// only validate required fields when necessary
|
|
2779
|
-
const pathDetails = _getPathsToValidate(this);
|
|
2780
|
-
|
|
2795
|
+
const pathDetails = _getPathsToValidate(this, pathsToValidate, pathsToSkip);
|
|
2796
|
+
const paths = shouldValidateModifiedOnly ?
|
|
2781
2797
|
pathDetails[0].filter((path) => this.$isModified(path)) :
|
|
2782
2798
|
pathDetails[0];
|
|
2783
2799
|
const skipSchemaValidators = pathDetails[1];
|
|
2784
2800
|
if (typeof pathsToValidate === 'string') {
|
|
2785
2801
|
pathsToValidate = pathsToValidate.split(' ');
|
|
2786
2802
|
}
|
|
2787
|
-
if (Array.isArray(pathsToValidate)) {
|
|
2788
|
-
paths = _handlePathsToValidate(paths, pathsToValidate);
|
|
2789
|
-
} else if (pathsToSkip) {
|
|
2790
|
-
paths = _handlePathsToSkip(paths, pathsToSkip);
|
|
2791
|
-
}
|
|
2792
2803
|
|
|
2793
2804
|
if (paths.length === 0) {
|
|
2794
2805
|
return immediate(function() {
|
|
@@ -2907,12 +2918,12 @@ function _handlePathsToValidate(paths, pathsToValidate) {
|
|
|
2907
2918
|
}
|
|
2908
2919
|
}
|
|
2909
2920
|
|
|
2910
|
-
const ret =
|
|
2921
|
+
const ret = new Set();
|
|
2911
2922
|
for (const path of paths) {
|
|
2912
2923
|
if (_pathsToValidate.has(path)) {
|
|
2913
|
-
ret.
|
|
2924
|
+
ret.add(path);
|
|
2914
2925
|
} else if (parentPaths.has(path)) {
|
|
2915
|
-
ret.
|
|
2926
|
+
ret.add(parentPaths.get(path));
|
|
2916
2927
|
}
|
|
2917
2928
|
}
|
|
2918
2929
|
return ret;
|
|
@@ -2924,8 +2935,8 @@ function _handlePathsToValidate(paths, pathsToValidate) {
|
|
|
2924
2935
|
|
|
2925
2936
|
function _handlePathsToSkip(paths, pathsToSkip) {
|
|
2926
2937
|
pathsToSkip = new Set(pathsToSkip);
|
|
2927
|
-
paths = paths.filter(p => !pathsToSkip.has(p));
|
|
2928
|
-
return paths;
|
|
2938
|
+
paths = Array.from(paths).filter(p => !pathsToSkip.has(p));
|
|
2939
|
+
return new Set(paths);
|
|
2929
2940
|
}
|
|
2930
2941
|
|
|
2931
2942
|
/**
|
|
@@ -2981,17 +2992,12 @@ Document.prototype.validateSync = function(pathsToValidate, options) {
|
|
|
2981
2992
|
}
|
|
2982
2993
|
|
|
2983
2994
|
// only validate required fields when necessary
|
|
2984
|
-
const pathDetails = _getPathsToValidate(this);
|
|
2985
|
-
|
|
2995
|
+
const pathDetails = _getPathsToValidate(this, pathsToValidate, pathsToSkip);
|
|
2996
|
+
const paths = shouldValidateModifiedOnly ?
|
|
2986
2997
|
pathDetails[0].filter((path) => this.$isModified(path)) :
|
|
2987
2998
|
pathDetails[0];
|
|
2988
2999
|
const skipSchemaValidators = pathDetails[1];
|
|
2989
3000
|
|
|
2990
|
-
if (Array.isArray(pathsToValidate)) {
|
|
2991
|
-
paths = _handlePathsToValidate(paths, pathsToValidate);
|
|
2992
|
-
} else if (Array.isArray(pathsToSkip)) {
|
|
2993
|
-
paths = _handlePathsToSkip(paths, pathsToSkip);
|
|
2994
|
-
}
|
|
2995
3001
|
const validating = {};
|
|
2996
3002
|
|
|
2997
3003
|
for (let i = 0, len = paths.length; i < len; ++i) {
|
|
@@ -32,7 +32,7 @@ module.exports = function applyDefaults(doc, fields, exclude, hasIncludedChildre
|
|
|
32
32
|
}
|
|
33
33
|
} else if (exclude === false && fields && !included) {
|
|
34
34
|
const hasSubpaths = type.$isSingleNested || type.$isMongooseDocumentArray;
|
|
35
|
-
if (curPath in fields || (hasSubpaths && hasIncludedChildren != null && hasIncludedChildren[curPath])) {
|
|
35
|
+
if (curPath in fields || (j === len - 1 && hasSubpaths && hasIncludedChildren != null && hasIncludedChildren[curPath])) {
|
|
36
36
|
included = true;
|
|
37
37
|
} else if (hasIncludedChildren != null && !hasIncludedChildren[curPath]) {
|
|
38
38
|
break;
|
|
@@ -7,6 +7,11 @@ const handleTimestampOption = require('../schema/handleTimestampOption');
|
|
|
7
7
|
const setDocumentTimestamps = require('./setDocumentTimestamps');
|
|
8
8
|
const symbols = require('../../schema/symbols');
|
|
9
9
|
|
|
10
|
+
const replaceOps = new Set([
|
|
11
|
+
'replaceOne',
|
|
12
|
+
'findOneAndReplace'
|
|
13
|
+
]);
|
|
14
|
+
|
|
10
15
|
module.exports = function setupTimestamps(schema, timestamps) {
|
|
11
16
|
const childHasTimestamp = schema.childSchemas.find(withTimestamp);
|
|
12
17
|
function withTimestamp(s) {
|
|
@@ -90,7 +95,7 @@ module.exports = function setupTimestamps(schema, timestamps) {
|
|
|
90
95
|
currentTime() :
|
|
91
96
|
this.model.base.now();
|
|
92
97
|
// Replacing with null update should still trigger timestamps
|
|
93
|
-
if (this.op
|
|
98
|
+
if (replaceOps.has(this.op) && this.getUpdate() == null) {
|
|
94
99
|
this.setUpdate({});
|
|
95
100
|
}
|
|
96
101
|
applyTimestampsToUpdate(now, createdAt, updatedAt, this.getUpdate(),
|
package/lib/model.js
CHANGED
|
@@ -1252,9 +1252,11 @@ for (const i in EventEmitter.prototype) {
|
|
|
1252
1252
|
* Mongoose calls this function automatically when a model is created using
|
|
1253
1253
|
* [`mongoose.model()`](/docs/api/mongoose.html#mongoose_Mongoose-model) or
|
|
1254
1254
|
* [`connection.model()`](/docs/api/connection.html#connection_Connection-model), so you
|
|
1255
|
-
* don't need to call
|
|
1256
|
-
*
|
|
1257
|
-
*
|
|
1255
|
+
* don't need to call `init()` to trigger index builds.
|
|
1256
|
+
*
|
|
1257
|
+
* However, you _may_ need to call `init()` to get back a promise that will resolve when your indexes are finished.
|
|
1258
|
+
* Calling `await Model.init()` is helpful if you need to wait for indexes to build before continuing.
|
|
1259
|
+
* For example, if you want to wait for unique indexes to build before continuing with a test case.
|
|
1258
1260
|
*
|
|
1259
1261
|
* #### Example:
|
|
1260
1262
|
*
|
|
@@ -1263,11 +1265,8 @@ for (const i in EventEmitter.prototype) {
|
|
|
1263
1265
|
* // `Event.init()` on your own.
|
|
1264
1266
|
* const Event = mongoose.model('Event', eventSchema);
|
|
1265
1267
|
*
|
|
1266
|
-
* Event.init()
|
|
1267
|
-
*
|
|
1268
|
-
* // over promises.
|
|
1269
|
-
* console.log('Indexes are done building!');
|
|
1270
|
-
* });
|
|
1268
|
+
* await Event.init();
|
|
1269
|
+
* console.log('Indexes are done building!');
|
|
1271
1270
|
*
|
|
1272
1271
|
* @api public
|
|
1273
1272
|
* @returns {Promise}
|
|
@@ -2952,7 +2951,7 @@ Model.startSession = function() {
|
|
|
2952
2951
|
* @param {Array|Object|*} doc(s)
|
|
2953
2952
|
* @param {Object} [options] see the [mongodb driver options](https://mongodb.github.io/node-mongodb-native/4.9/classes/Collection.html#insertMany)
|
|
2954
2953
|
* @param {Boolean} [options.ordered=true] if true, will fail fast on the first error encountered. If false, will insert all the documents it can and report errors later. An `insertMany()` with `ordered = false` is called an "unordered" `insertMany()`.
|
|
2955
|
-
* @param {Boolean} [options.rawResult=false] if false, the returned promise resolves to the documents that passed mongoose document validation. If `true`, will return the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/InsertManyResult.html) with a `mongoose` property that contains `validationErrors` if this is an unordered `insertMany`.
|
|
2954
|
+
* @param {Boolean} [options.rawResult=false] if false, the returned promise resolves to the documents that passed mongoose document validation. If `true`, will return the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/InsertManyResult.html) with a `mongoose` property that contains `validationErrors` and `results` if this is an unordered `insertMany`.
|
|
2956
2955
|
* @param {Boolean} [options.lean=false] if `true`, skips hydrating and validating the documents. This option is useful if you need the extra performance, but Mongoose won't validate the documents before inserting.
|
|
2957
2956
|
* @param {Number} [options.limit=null] this limits the number of documents being processed (validation/casting) by mongoose in parallel, this does **NOT** send the documents in batches to MongoDB. Use this option if you're processing a large number of documents and your app is running out of memory.
|
|
2958
2957
|
* @param {String|Object|Array} [options.populate=null] populates the result documents. This option is a no-op if `rawResult` is set.
|
|
@@ -3009,6 +3008,7 @@ Model.$__insertMany = function(arr, options, callback) {
|
|
|
3009
3008
|
|
|
3010
3009
|
const validationErrors = [];
|
|
3011
3010
|
const validationErrorsToOriginalOrder = new Map();
|
|
3011
|
+
const results = ordered ? null : new Array(arr.length);
|
|
3012
3012
|
const toExecute = arr.map((doc, index) =>
|
|
3013
3013
|
callback => {
|
|
3014
3014
|
if (!(doc instanceof _this)) {
|
|
@@ -3034,8 +3034,8 @@ Model.$__insertMany = function(arr, options, callback) {
|
|
|
3034
3034
|
if (ordered === false) {
|
|
3035
3035
|
validationErrors.push(error);
|
|
3036
3036
|
validationErrorsToOriginalOrder.set(error, index);
|
|
3037
|
-
|
|
3038
|
-
return;
|
|
3037
|
+
results[index] = error;
|
|
3038
|
+
return callback(null, null);
|
|
3039
3039
|
}
|
|
3040
3040
|
callback(error);
|
|
3041
3041
|
}
|
|
@@ -3108,10 +3108,17 @@ Model.$__insertMany = function(arr, options, callback) {
|
|
|
3108
3108
|
|
|
3109
3109
|
if (rawResult) {
|
|
3110
3110
|
if (ordered === false) {
|
|
3111
|
+
for (let i = 0; i < results.length; ++i) {
|
|
3112
|
+
if (results[i] === void 0) {
|
|
3113
|
+
results[i] = docs[i];
|
|
3114
|
+
}
|
|
3115
|
+
}
|
|
3116
|
+
|
|
3111
3117
|
// Decorate with mongoose validation errors in case of unordered,
|
|
3112
3118
|
// because then still do `insertMany()`
|
|
3113
3119
|
res.mongoose = {
|
|
3114
|
-
validationErrors: validationErrors
|
|
3120
|
+
validationErrors: validationErrors,
|
|
3121
|
+
results: results
|
|
3115
3122
|
};
|
|
3116
3123
|
}
|
|
3117
3124
|
return callback(null, res);
|
|
@@ -3143,10 +3150,24 @@ Model.$__insertMany = function(arr, options, callback) {
|
|
|
3143
3150
|
const erroredIndexes = new Set((error && error.writeErrors || []).map(err => err.index));
|
|
3144
3151
|
|
|
3145
3152
|
for (let i = 0; i < error.writeErrors.length; ++i) {
|
|
3153
|
+
const originalIndex = validDocIndexToOriginalIndex.get(error.writeErrors[i].index);
|
|
3146
3154
|
error.writeErrors[i] = {
|
|
3147
3155
|
...error.writeErrors[i],
|
|
3148
|
-
index:
|
|
3156
|
+
index: originalIndex
|
|
3149
3157
|
};
|
|
3158
|
+
if (!ordered) {
|
|
3159
|
+
results[originalIndex] = error.writeErrors[i];
|
|
3160
|
+
}
|
|
3161
|
+
}
|
|
3162
|
+
|
|
3163
|
+
if (!ordered) {
|
|
3164
|
+
for (let i = 0; i < results.length; ++i) {
|
|
3165
|
+
if (results[i] === void 0) {
|
|
3166
|
+
results[i] = docs[i];
|
|
3167
|
+
}
|
|
3168
|
+
}
|
|
3169
|
+
|
|
3170
|
+
error.results = results;
|
|
3150
3171
|
}
|
|
3151
3172
|
|
|
3152
3173
|
let firstErroredIndex = -1;
|
|
@@ -3174,7 +3195,8 @@ Model.$__insertMany = function(arr, options, callback) {
|
|
|
3174
3195
|
|
|
3175
3196
|
if (rawResult && ordered === false) {
|
|
3176
3197
|
error.mongoose = {
|
|
3177
|
-
validationErrors: validationErrors
|
|
3198
|
+
validationErrors: validationErrors,
|
|
3199
|
+
results: results
|
|
3178
3200
|
};
|
|
3179
3201
|
}
|
|
3180
3202
|
|
package/lib/query.js
CHANGED
|
@@ -4319,6 +4319,10 @@ Query.prototype.exec = async function exec(op) {
|
|
|
4319
4319
|
try {
|
|
4320
4320
|
await _executePreHooks(this);
|
|
4321
4321
|
res = await this[thunk]();
|
|
4322
|
+
|
|
4323
|
+
for (const fn of this._transforms) {
|
|
4324
|
+
res = fn(res);
|
|
4325
|
+
}
|
|
4322
4326
|
} catch (err) {
|
|
4323
4327
|
if (err instanceof Kareem.skipWrappedFunction) {
|
|
4324
4328
|
res = err.args[0];
|
|
@@ -4327,10 +4331,6 @@ Query.prototype.exec = async function exec(op) {
|
|
|
4327
4331
|
}
|
|
4328
4332
|
}
|
|
4329
4333
|
|
|
4330
|
-
for (const fn of this._transforms) {
|
|
4331
|
-
res = fn(res);
|
|
4332
|
-
}
|
|
4333
|
-
|
|
4334
4334
|
res = await _executePostHooks(this, res, error);
|
|
4335
4335
|
|
|
4336
4336
|
await _executePostExecHooks(this);
|
|
@@ -4482,7 +4482,8 @@ Query.prototype.finally = function(onFinally) {
|
|
|
4482
4482
|
*
|
|
4483
4483
|
* @return {String}
|
|
4484
4484
|
* @api public
|
|
4485
|
-
* @method toStringTag
|
|
4485
|
+
* @method [Symbol.toStringTag]
|
|
4486
|
+
* @memberOf Query
|
|
4486
4487
|
*/
|
|
4487
4488
|
|
|
4488
4489
|
Query.prototype[Symbol.toStringTag] = function toString() {
|
|
@@ -5192,7 +5193,7 @@ Query.prototype.nearSphere = function() {
|
|
|
5192
5193
|
* `Symbol.asyncIterator` is undefined, that means your Node.js version does not
|
|
5193
5194
|
* support async iterators.
|
|
5194
5195
|
*
|
|
5195
|
-
* @method Symbol.asyncIterator
|
|
5196
|
+
* @method [Symbol.asyncIterator]
|
|
5196
5197
|
* @memberOf Query
|
|
5197
5198
|
* @instance
|
|
5198
5199
|
* @api public
|
|
@@ -416,6 +416,8 @@ DocumentArrayPath.prototype.cast = function(value, doc, init, prev, options) {
|
|
|
416
416
|
|
|
417
417
|
options = options || {};
|
|
418
418
|
|
|
419
|
+
const path = options.path || this.path;
|
|
420
|
+
|
|
419
421
|
if (!Array.isArray(value)) {
|
|
420
422
|
if (!init && !DocumentArrayPath.options.castNonArrays) {
|
|
421
423
|
throw new CastError('DocumentArray', value, this.path, null, this);
|
|
@@ -423,7 +425,7 @@ DocumentArrayPath.prototype.cast = function(value, doc, init, prev, options) {
|
|
|
423
425
|
// gh-2442 mark whole array as modified if we're initializing a doc from
|
|
424
426
|
// the db and the path isn't an array in the document
|
|
425
427
|
if (!!doc && init) {
|
|
426
|
-
doc.markModified(
|
|
428
|
+
doc.markModified(path);
|
|
427
429
|
}
|
|
428
430
|
return this.cast([value], doc, init, prev, options);
|
|
429
431
|
}
|
|
@@ -431,7 +433,7 @@ DocumentArrayPath.prototype.cast = function(value, doc, init, prev, options) {
|
|
|
431
433
|
// We need to create a new array, otherwise change tracking will
|
|
432
434
|
// update the old doc (gh-4449)
|
|
433
435
|
if (!options.skipDocumentArrayCast || utils.isMongooseDocumentArray(value)) {
|
|
434
|
-
value = new MongooseDocumentArray(value,
|
|
436
|
+
value = new MongooseDocumentArray(value, path, doc);
|
|
435
437
|
}
|
|
436
438
|
|
|
437
439
|
if (prev != null) {
|
|
@@ -439,7 +441,7 @@ DocumentArrayPath.prototype.cast = function(value, doc, init, prev, options) {
|
|
|
439
441
|
}
|
|
440
442
|
|
|
441
443
|
if (options.arrayPathIndex != null) {
|
|
442
|
-
value[arrayPathSymbol] =
|
|
444
|
+
value[arrayPathSymbol] = path + '.' + options.arrayPathIndex;
|
|
443
445
|
}
|
|
444
446
|
|
|
445
447
|
const rawArray = utils.isMongooseDocumentArray(value) ? value.__array : value;
|
package/lib/schema.js
CHANGED
|
@@ -734,8 +734,15 @@ Schema.prototype.add = function add(obj, prefix) {
|
|
|
734
734
|
if (prefix) {
|
|
735
735
|
this.nested[prefix.substring(0, prefix.length - 1)] = true;
|
|
736
736
|
}
|
|
737
|
-
|
|
738
|
-
const
|
|
737
|
+
|
|
738
|
+
const childSchemaOptions = {};
|
|
739
|
+
if (this._userProvidedOptions.typeKey) {
|
|
740
|
+
childSchemaOptions.typeKey = this._userProvidedOptions.typeKey;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
const _schema = new Schema(_typeDef, childSchemaOptions);
|
|
744
|
+
_schema.$implicitlyCreated = true;
|
|
745
|
+
const schemaWrappedPath = Object.assign({}, val, { [typeKey]: _schema });
|
|
739
746
|
this.path(prefix + key, schemaWrappedPath);
|
|
740
747
|
} else {
|
|
741
748
|
// Either the type is non-POJO or we interpret it as Mixed anyway
|
|
@@ -1322,6 +1329,7 @@ Schema.prototype.interpretAsType = function(path, obj, options) {
|
|
|
1322
1329
|
} else if (Schema.Types.DocumentArray.defaultOptions._id != null) {
|
|
1323
1330
|
childSchemaOptions._id = Schema.Types.DocumentArray.defaultOptions._id;
|
|
1324
1331
|
}
|
|
1332
|
+
|
|
1325
1333
|
const childSchema = new Schema(castFromTypeKey, childSchemaOptions);
|
|
1326
1334
|
childSchema.$implicitlyCreated = true;
|
|
1327
1335
|
return new MongooseTypes.DocumentArray(path, childSchema, obj);
|
|
@@ -1365,7 +1373,6 @@ Schema.prototype.interpretAsType = function(path, obj, options) {
|
|
|
1365
1373
|
}
|
|
1366
1374
|
|
|
1367
1375
|
if (type && type.instanceOfSchema) {
|
|
1368
|
-
|
|
1369
1376
|
return new MongooseTypes.Subdocument(type, path, obj);
|
|
1370
1377
|
}
|
|
1371
1378
|
|
|
@@ -2210,11 +2217,15 @@ Schema.prototype.virtual = function(name, options) {
|
|
|
2210
2217
|
}
|
|
2211
2218
|
|
|
2212
2219
|
// Workaround for gh-8198: if virtual is under document array, make a fake
|
|
2213
|
-
// virtual. See gh-8210
|
|
2220
|
+
// virtual. See gh-8210, gh-13189
|
|
2214
2221
|
const parts = name.split('.');
|
|
2215
2222
|
let cur = parts[0];
|
|
2216
2223
|
for (let i = 0; i < parts.length - 1; ++i) {
|
|
2217
|
-
if (this.paths[cur]
|
|
2224
|
+
if (this.paths[cur] == null) {
|
|
2225
|
+
continue;
|
|
2226
|
+
}
|
|
2227
|
+
|
|
2228
|
+
if (this.paths[cur].$isMongooseDocumentArray || this.paths[cur].$isSingleNested) {
|
|
2218
2229
|
const remnant = parts.slice(i + 1).join('.');
|
|
2219
2230
|
this.paths[cur].schema.virtual(remnant, options);
|
|
2220
2231
|
break;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongoose",
|
|
3
3
|
"description": "Mongoose MongoDB ODM",
|
|
4
|
-
"version": "7.0.
|
|
4
|
+
"version": "7.0.3",
|
|
5
5
|
"author": "Guillermo Rauch <guillermo@learnboost.com>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mongodb",
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
"dotenv": "16.0.3",
|
|
47
47
|
"dox": "1.0.0",
|
|
48
48
|
"eslint": "8.35.0",
|
|
49
|
+
"eslint-plugin-markdown": "^3.0.0",
|
|
49
50
|
"eslint-plugin-mocha-no-only": "1.1.1",
|
|
50
51
|
"express": "^4.18.1",
|
|
51
52
|
"highlight.js": "11.7.0",
|
|
@@ -75,7 +76,7 @@
|
|
|
75
76
|
"docs:clean:stable": "rimraf index.html && rimraf -rf ./docs/*.html && rimraf -rf ./docs/api && rimraf -rf ./docs/tutorials/*.html && rimraf -rf ./docs/typescript/*.html && rimraf -rf ./docs/*.html && rimraf -rf ./docs/source/_docs && rimraf -rf ./tmp",
|
|
76
77
|
"docs:clean:5x": "rimraf index.html && rimraf -rf ./docs/5.x && rimraf -rf ./docs/source/_docs && rimraf -rf ./tmp",
|
|
77
78
|
"docs:clean:6x": "rimraf index.html && rimraf -rf ./docs/6.x && rimraf -rf ./docs/source/_docs && rimraf -rf ./tmp",
|
|
78
|
-
"docs:copy:tmp": "mkdirp ./tmp/docs/css && mkdirp ./tmp/docs/js && mkdirp ./tmp/docs/images && mkdirp ./tmp/docs/tutorials && mkdirp ./tmp/docs/typescript && ncp ./docs/css ./tmp/docs/css --filter=.css$ && ncp ./docs/js ./tmp/docs/js --filter=.js$ && ncp ./docs/images ./tmp/docs/images && ncp ./docs/tutorials ./tmp/docs/tutorials && ncp ./docs/typescript ./tmp/docs/typescript && cp index.html ./tmp && cp docs/*.html ./tmp/docs/",
|
|
79
|
+
"docs:copy:tmp": "mkdirp ./tmp/docs/css && mkdirp ./tmp/docs/js && mkdirp ./tmp/docs/images && mkdirp ./tmp/docs/tutorials && mkdirp ./tmp/docs/typescript && mkdirp ./tmp/docs/api && ncp ./docs/css ./tmp/docs/css --filter=.css$ && ncp ./docs/js ./tmp/docs/js --filter=.js$ && ncp ./docs/images ./tmp/docs/images && ncp ./docs/tutorials ./tmp/docs/tutorials && ncp ./docs/typescript ./tmp/docs/typescript && ncp ./docs/api ./tmp/docs/api && cp index.html ./tmp && cp docs/*.html ./tmp/docs/",
|
|
79
80
|
"docs:copy:tmp:5x": "rimraf ./docs/5.x && ncp ./tmp ./docs/5.x",
|
|
80
81
|
"docs:copy:tmp:6x": "rimraf ./docs/6.x && ncp ./tmp ./docs/6.x",
|
|
81
82
|
"docs:checkout:gh-pages": "git checkout gh-pages",
|
|
@@ -83,6 +84,7 @@
|
|
|
83
84
|
"docs:checkout:6x": "git checkout 6.x",
|
|
84
85
|
"docs:generate": "node ./scripts/website.js",
|
|
85
86
|
"docs:generate:search": "node ./scripts/generateSearch.js",
|
|
87
|
+
"docs:generate:sponsorData": "node ./scripts/loadSponsorData.js",
|
|
86
88
|
"docs:merge:stable": "git merge master",
|
|
87
89
|
"docs:merge:5x": "git merge 5.x",
|
|
88
90
|
"docs:merge:6x": "git merge 6.x",
|
|
@@ -95,6 +97,7 @@
|
|
|
95
97
|
"lint": "eslint .",
|
|
96
98
|
"lint-js": "eslint . --ext .js",
|
|
97
99
|
"lint-ts": "eslint . --ext .ts",
|
|
100
|
+
"lint-md": "eslint . --ext .md",
|
|
98
101
|
"build-browser": "(rm ./dist/* || true) && node ./scripts/build-browser.js",
|
|
99
102
|
"prepublishOnly": "npm run build-browser",
|
|
100
103
|
"release": "git pull && git push origin master --tags && npm publish",
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
let config;
|
|
4
|
+
try {
|
|
5
|
+
config = require('../.config.js');
|
|
6
|
+
} finally {
|
|
7
|
+
if (!config || !config.uri) {
|
|
8
|
+
console.error('No Config or config.URI given, please create a .config.js file with those values in the root of the repository');
|
|
9
|
+
process.exit(-1);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
4
12
|
const cheerio = require('cheerio');
|
|
5
13
|
const filemap = require('../docs/source');
|
|
6
14
|
const fs = require('fs');
|
|
@@ -30,25 +38,27 @@ const Content = mongoose.model('Content', contentSchema, 'Content');
|
|
|
30
38
|
|
|
31
39
|
const contents = [];
|
|
32
40
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
contents.push(content);
|
|
49
|
-
}
|
|
41
|
+
const api = require('../docs/source/api');
|
|
42
|
+
|
|
43
|
+
// API docs are special, because they are not added to the file-map individually currently and use different properties
|
|
44
|
+
for (const _class of api.docs) {
|
|
45
|
+
for (const prop of _class.props) {
|
|
46
|
+
const content = new Content({
|
|
47
|
+
title: `API: ${prop.name}`,
|
|
48
|
+
body: prop.description,
|
|
49
|
+
url: `api/${_class.fileName}.html#${prop.anchorId}`
|
|
50
|
+
});
|
|
51
|
+
const err = content.validateSync();
|
|
52
|
+
if (err != null) {
|
|
53
|
+
console.error(content);
|
|
54
|
+
throw err;
|
|
50
55
|
}
|
|
51
|
-
|
|
56
|
+
contents.push(content);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
for (const [filename, file] of Object.entries(filemap)) {
|
|
61
|
+
if (file.markdown) {
|
|
52
62
|
let text = fs.readFileSync(filename, 'utf8');
|
|
53
63
|
text = markdown.parse(text);
|
|
54
64
|
|
|
@@ -120,11 +130,6 @@ run().catch(async error => {
|
|
|
120
130
|
});
|
|
121
131
|
|
|
122
132
|
async function run() {
|
|
123
|
-
if (!config || !config.uri) {
|
|
124
|
-
console.error('No Config or config.URI given, please create a .config.js file with those values');
|
|
125
|
-
process.exit(-1);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
133
|
await mongoose.connect(config.uri, { dbName: 'mongoose', serverSelectionTimeoutMS: 5000 });
|
|
129
134
|
|
|
130
135
|
// wait for the index to be created
|
|
@@ -152,5 +157,7 @@ async function run() {
|
|
|
152
157
|
|
|
153
158
|
console.log(results.map(res => res.url));
|
|
154
159
|
|
|
160
|
+
console.log(`Added ${contents.length} Content`);
|
|
161
|
+
|
|
155
162
|
process.exit(0);
|
|
156
163
|
}
|