mongoose 8.2.4 → 8.3.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/dist/browser.umd.js +1 -1
- package/lib/document.js +141 -56
- package/lib/model.js +13 -2
- package/lib/query.js +11 -3
- package/lib/schema/documentArray.js +2 -2
- package/lib/schema.js +8 -4
- package/lib/schemaType.js +18 -1
- package/package.json +11 -11
- package/types/index.d.ts +5 -31
- package/types/middlewares.d.ts +5 -4
- package/types/query.d.ts +4 -1
- package/types/schematypes.d.ts +10 -3
package/lib/document.js
CHANGED
|
@@ -2756,47 +2756,7 @@ function _getPathsToValidate(doc, pathsToValidate, pathsToSkip) {
|
|
|
2756
2756
|
|
|
2757
2757
|
// gh-661: if a whole array is modified, make sure to run validation on all
|
|
2758
2758
|
// the children as well
|
|
2759
|
-
|
|
2760
|
-
const _pathType = doc.$__schema.path(path);
|
|
2761
|
-
if (!_pathType) {
|
|
2762
|
-
continue;
|
|
2763
|
-
}
|
|
2764
|
-
|
|
2765
|
-
if (!_pathType.$isMongooseArray ||
|
|
2766
|
-
// To avoid potential performance issues, skip doc arrays whose children
|
|
2767
|
-
// are not required. `getPositionalPathType()` may be slow, so avoid
|
|
2768
|
-
// it unless we have a case of #6364
|
|
2769
|
-
(!Array.isArray(_pathType) &&
|
|
2770
|
-
_pathType.$isMongooseDocumentArray &&
|
|
2771
|
-
!(_pathType && _pathType.schemaOptions && _pathType.schemaOptions.required))) {
|
|
2772
|
-
continue;
|
|
2773
|
-
}
|
|
2774
|
-
|
|
2775
|
-
// gh-11380: optimization. If the array isn't a document array and there's no validators
|
|
2776
|
-
// on the array type, there's no need to run validation on the individual array elements.
|
|
2777
|
-
if (_pathType.$isMongooseArray &&
|
|
2778
|
-
!_pathType.$isMongooseDocumentArray && // Skip document arrays...
|
|
2779
|
-
!_pathType.$embeddedSchemaType.$isMongooseArray && // and arrays of arrays
|
|
2780
|
-
_pathType.$embeddedSchemaType.validators.length === 0) {
|
|
2781
|
-
continue;
|
|
2782
|
-
}
|
|
2783
|
-
|
|
2784
|
-
const val = doc.$__getValue(path);
|
|
2785
|
-
_pushNestedArrayPaths(val, paths, path);
|
|
2786
|
-
}
|
|
2787
|
-
|
|
2788
|
-
function _pushNestedArrayPaths(val, paths, path) {
|
|
2789
|
-
if (val != null) {
|
|
2790
|
-
const numElements = val.length;
|
|
2791
|
-
for (let j = 0; j < numElements; ++j) {
|
|
2792
|
-
if (Array.isArray(val[j])) {
|
|
2793
|
-
_pushNestedArrayPaths(val[j], paths, path + '.' + j);
|
|
2794
|
-
} else {
|
|
2795
|
-
paths.add(path + '.' + j);
|
|
2796
|
-
}
|
|
2797
|
-
}
|
|
2798
|
-
}
|
|
2799
|
-
}
|
|
2759
|
+
_addArrayPathsToValidate(doc, paths);
|
|
2800
2760
|
|
|
2801
2761
|
const flattenOptions = { skipArrays: true };
|
|
2802
2762
|
for (const pathToCheck of paths) {
|
|
@@ -2841,12 +2801,58 @@ function _getPathsToValidate(doc, pathsToValidate, pathsToSkip) {
|
|
|
2841
2801
|
return [paths, doValidateOptions];
|
|
2842
2802
|
}
|
|
2843
2803
|
|
|
2804
|
+
function _addArrayPathsToValidate(doc, paths) {
|
|
2805
|
+
for (const path of paths) {
|
|
2806
|
+
const _pathType = doc.$__schema.path(path);
|
|
2807
|
+
if (!_pathType) {
|
|
2808
|
+
continue;
|
|
2809
|
+
}
|
|
2810
|
+
|
|
2811
|
+
if (!_pathType.$isMongooseArray ||
|
|
2812
|
+
// To avoid potential performance issues, skip doc arrays whose children
|
|
2813
|
+
// are not required. `getPositionalPathType()` may be slow, so avoid
|
|
2814
|
+
// it unless we have a case of #6364
|
|
2815
|
+
(!Array.isArray(_pathType) &&
|
|
2816
|
+
_pathType.$isMongooseDocumentArray &&
|
|
2817
|
+
!(_pathType && _pathType.schemaOptions && _pathType.schemaOptions.required))) {
|
|
2818
|
+
continue;
|
|
2819
|
+
}
|
|
2820
|
+
|
|
2821
|
+
// gh-11380: optimization. If the array isn't a document array and there's no validators
|
|
2822
|
+
// on the array type, there's no need to run validation on the individual array elements.
|
|
2823
|
+
if (_pathType.$isMongooseArray &&
|
|
2824
|
+
!_pathType.$isMongooseDocumentArray && // Skip document arrays...
|
|
2825
|
+
!_pathType.$embeddedSchemaType.$isMongooseArray && // and arrays of arrays
|
|
2826
|
+
_pathType.$embeddedSchemaType.validators.length === 0) {
|
|
2827
|
+
continue;
|
|
2828
|
+
}
|
|
2829
|
+
|
|
2830
|
+
const val = doc.$__getValue(path);
|
|
2831
|
+
_pushNestedArrayPaths(val, paths, path);
|
|
2832
|
+
}
|
|
2833
|
+
}
|
|
2834
|
+
|
|
2835
|
+
function _pushNestedArrayPaths(val, paths, path) {
|
|
2836
|
+
if (val != null) {
|
|
2837
|
+
const numElements = val.length;
|
|
2838
|
+
for (let j = 0; j < numElements; ++j) {
|
|
2839
|
+
if (Array.isArray(val[j])) {
|
|
2840
|
+
_pushNestedArrayPaths(val[j], paths, path + '.' + j);
|
|
2841
|
+
} else {
|
|
2842
|
+
paths.add(path + '.' + j);
|
|
2843
|
+
}
|
|
2844
|
+
}
|
|
2845
|
+
}
|
|
2846
|
+
}
|
|
2847
|
+
|
|
2844
2848
|
/*!
|
|
2845
2849
|
* ignore
|
|
2846
2850
|
*/
|
|
2847
2851
|
|
|
2848
2852
|
Document.prototype.$__validate = function(pathsToValidate, options, callback) {
|
|
2849
|
-
if (
|
|
2853
|
+
if (this.$__.saveOptions && this.$__.saveOptions.pathsToSave && !pathsToValidate) {
|
|
2854
|
+
pathsToValidate = [...this.$__.saveOptions.pathsToSave];
|
|
2855
|
+
} else if (typeof pathsToValidate === 'function') {
|
|
2850
2856
|
callback = pathsToValidate;
|
|
2851
2857
|
options = null;
|
|
2852
2858
|
pathsToValidate = null;
|
|
@@ -2868,6 +2874,19 @@ Document.prototype.$__validate = function(pathsToValidate, options, callback) {
|
|
|
2868
2874
|
shouldValidateModifiedOnly = this.$__schema.options.validateModifiedOnly;
|
|
2869
2875
|
}
|
|
2870
2876
|
|
|
2877
|
+
const validateAllPaths = options && options.validateAllPaths;
|
|
2878
|
+
if (validateAllPaths) {
|
|
2879
|
+
if (pathsToSkip) {
|
|
2880
|
+
throw new TypeError('Cannot set both `validateAllPaths` and `pathsToSkip`');
|
|
2881
|
+
}
|
|
2882
|
+
if (pathsToValidate) {
|
|
2883
|
+
throw new TypeError('Cannot set both `validateAllPaths` and `pathsToValidate`');
|
|
2884
|
+
}
|
|
2885
|
+
if (hasValidateModifiedOnlyOption && shouldValidateModifiedOnly) {
|
|
2886
|
+
throw new TypeError('Cannot set both `validateAllPaths` and `validateModifiedOnly`');
|
|
2887
|
+
}
|
|
2888
|
+
}
|
|
2889
|
+
|
|
2871
2890
|
const _this = this;
|
|
2872
2891
|
const _complete = () => {
|
|
2873
2892
|
let validationError = this.$__.validationError;
|
|
@@ -2905,11 +2924,33 @@ Document.prototype.$__validate = function(pathsToValidate, options, callback) {
|
|
|
2905
2924
|
};
|
|
2906
2925
|
|
|
2907
2926
|
// only validate required fields when necessary
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2927
|
+
let paths;
|
|
2928
|
+
let doValidateOptionsByPath;
|
|
2929
|
+
if (validateAllPaths) {
|
|
2930
|
+
paths = new Set(Object.keys(this.$__schema.paths));
|
|
2931
|
+
// gh-661: if a whole array is modified, make sure to run validation on all
|
|
2932
|
+
// the children as well
|
|
2933
|
+
for (const path of paths) {
|
|
2934
|
+
const schemaType = this.$__schema.path(path);
|
|
2935
|
+
if (!schemaType || !schemaType.$isMongooseArray) {
|
|
2936
|
+
continue;
|
|
2937
|
+
}
|
|
2938
|
+
const val = this.$__getValue(path);
|
|
2939
|
+
if (!val) {
|
|
2940
|
+
continue;
|
|
2941
|
+
}
|
|
2942
|
+
_pushNestedArrayPaths(val, paths, path);
|
|
2943
|
+
}
|
|
2944
|
+
paths = [...paths];
|
|
2945
|
+
doValidateOptionsByPath = {};
|
|
2946
|
+
} else {
|
|
2947
|
+
const pathDetails = _getPathsToValidate(this, pathsToValidate, pathsToSkip);
|
|
2948
|
+
paths = shouldValidateModifiedOnly ?
|
|
2949
|
+
pathDetails[0].filter((path) => this.$isModified(path)) :
|
|
2950
|
+
pathDetails[0];
|
|
2951
|
+
doValidateOptionsByPath = pathDetails[1];
|
|
2952
|
+
}
|
|
2953
|
+
|
|
2913
2954
|
if (typeof pathsToValidate === 'string') {
|
|
2914
2955
|
pathsToValidate = pathsToValidate.split(' ');
|
|
2915
2956
|
}
|
|
@@ -2929,8 +2970,19 @@ Document.prototype.$__validate = function(pathsToValidate, options, callback) {
|
|
|
2929
2970
|
const validated = {};
|
|
2930
2971
|
let total = 0;
|
|
2931
2972
|
|
|
2932
|
-
|
|
2933
|
-
|
|
2973
|
+
let pathsToSave = this.$__.saveOptions?.pathsToSave;
|
|
2974
|
+
if (Array.isArray(pathsToSave)) {
|
|
2975
|
+
pathsToSave = new Set(pathsToSave);
|
|
2976
|
+
for (const path of paths) {
|
|
2977
|
+
if (!pathsToSave.has(path)) {
|
|
2978
|
+
continue;
|
|
2979
|
+
}
|
|
2980
|
+
validatePath(path);
|
|
2981
|
+
}
|
|
2982
|
+
} else {
|
|
2983
|
+
for (const path of paths) {
|
|
2984
|
+
validatePath(path);
|
|
2985
|
+
}
|
|
2934
2986
|
}
|
|
2935
2987
|
|
|
2936
2988
|
function validatePath(path) {
|
|
@@ -2979,7 +3031,8 @@ Document.prototype.$__validate = function(pathsToValidate, options, callback) {
|
|
|
2979
3031
|
const doValidateOptions = {
|
|
2980
3032
|
...doValidateOptionsByPath[path],
|
|
2981
3033
|
path: path,
|
|
2982
|
-
validateModifiedOnly: shouldValidateModifiedOnly
|
|
3034
|
+
validateModifiedOnly: shouldValidateModifiedOnly,
|
|
3035
|
+
validateAllPaths
|
|
2983
3036
|
};
|
|
2984
3037
|
|
|
2985
3038
|
schemaType.doValidate(val, function(err) {
|
|
@@ -3097,6 +3150,16 @@ Document.prototype.validateSync = function(pathsToValidate, options) {
|
|
|
3097
3150
|
|
|
3098
3151
|
let pathsToSkip = options && options.pathsToSkip;
|
|
3099
3152
|
|
|
3153
|
+
const validateAllPaths = options && options.validateAllPaths;
|
|
3154
|
+
if (validateAllPaths) {
|
|
3155
|
+
if (pathsToSkip) {
|
|
3156
|
+
throw new TypeError('Cannot set both `validateAllPaths` and `pathsToSkip`');
|
|
3157
|
+
}
|
|
3158
|
+
if (pathsToValidate) {
|
|
3159
|
+
throw new TypeError('Cannot set both `validateAllPaths` and `pathsToValidate`');
|
|
3160
|
+
}
|
|
3161
|
+
}
|
|
3162
|
+
|
|
3100
3163
|
if (typeof pathsToValidate === 'string') {
|
|
3101
3164
|
const isOnePathOnly = pathsToValidate.indexOf(' ') === -1;
|
|
3102
3165
|
pathsToValidate = isOnePathOnly ? [pathsToValidate] : pathsToValidate.split(' ');
|
|
@@ -3105,11 +3168,32 @@ Document.prototype.validateSync = function(pathsToValidate, options) {
|
|
|
3105
3168
|
}
|
|
3106
3169
|
|
|
3107
3170
|
// only validate required fields when necessary
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3171
|
+
let paths;
|
|
3172
|
+
let skipSchemaValidators;
|
|
3173
|
+
if (validateAllPaths) {
|
|
3174
|
+
paths = new Set(Object.keys(this.$__schema.paths));
|
|
3175
|
+
// gh-661: if a whole array is modified, make sure to run validation on all
|
|
3176
|
+
// the children as well
|
|
3177
|
+
for (const path of paths) {
|
|
3178
|
+
const schemaType = this.$__schema.path(path);
|
|
3179
|
+
if (!schemaType || !schemaType.$isMongooseArray) {
|
|
3180
|
+
continue;
|
|
3181
|
+
}
|
|
3182
|
+
const val = this.$__getValue(path);
|
|
3183
|
+
if (!val) {
|
|
3184
|
+
continue;
|
|
3185
|
+
}
|
|
3186
|
+
_pushNestedArrayPaths(val, paths, path);
|
|
3187
|
+
}
|
|
3188
|
+
paths = [...paths];
|
|
3189
|
+
skipSchemaValidators = {};
|
|
3190
|
+
} else {
|
|
3191
|
+
const pathDetails = _getPathsToValidate(this, pathsToValidate, pathsToSkip);
|
|
3192
|
+
paths = shouldValidateModifiedOnly ?
|
|
3193
|
+
pathDetails[0].filter((path) => this.$isModified(path)) :
|
|
3194
|
+
pathDetails[0];
|
|
3195
|
+
skipSchemaValidators = pathDetails[1];
|
|
3196
|
+
}
|
|
3113
3197
|
|
|
3114
3198
|
const validating = {};
|
|
3115
3199
|
|
|
@@ -3134,7 +3218,8 @@ Document.prototype.validateSync = function(pathsToValidate, options) {
|
|
|
3134
3218
|
const err = p.doValidateSync(val, _this, {
|
|
3135
3219
|
skipSchemaValidators: skipSchemaValidators[path],
|
|
3136
3220
|
path: path,
|
|
3137
|
-
validateModifiedOnly: shouldValidateModifiedOnly
|
|
3221
|
+
validateModifiedOnly: shouldValidateModifiedOnly,
|
|
3222
|
+
validateAllPaths
|
|
3138
3223
|
});
|
|
3139
3224
|
if (err) {
|
|
3140
3225
|
const isSubdoc = p.$isSingleNested ||
|
package/lib/model.js
CHANGED
|
@@ -298,7 +298,6 @@ Model.prototype.$__handleSave = function(options, callback) {
|
|
|
298
298
|
if (!saveOptions.hasOwnProperty('session') && session != null) {
|
|
299
299
|
saveOptions.session = session;
|
|
300
300
|
}
|
|
301
|
-
|
|
302
301
|
if (this.$isNew) {
|
|
303
302
|
// send entire doc
|
|
304
303
|
const obj = this.toObject(saveToObjectOptions);
|
|
@@ -335,6 +334,18 @@ Model.prototype.$__handleSave = function(options, callback) {
|
|
|
335
334
|
// since it already exists
|
|
336
335
|
this.$__.inserting = false;
|
|
337
336
|
const delta = this.$__delta();
|
|
337
|
+
|
|
338
|
+
if (options.pathsToSave) {
|
|
339
|
+
for (const key in delta[1]['$set']) {
|
|
340
|
+
if (options.pathsToSave.includes(key)) {
|
|
341
|
+
continue;
|
|
342
|
+
} else if (options.pathsToSave.some(pathToSave => key.slice(0, pathToSave.length) === pathToSave && key.charAt(pathToSave.length) === '.')) {
|
|
343
|
+
continue;
|
|
344
|
+
} else {
|
|
345
|
+
delete delta[1]['$set'][key];
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
338
349
|
if (delta) {
|
|
339
350
|
if (delta instanceof MongooseError) {
|
|
340
351
|
callback(delta);
|
|
@@ -521,6 +532,7 @@ function generateVersionError(doc, modifiedPaths) {
|
|
|
521
532
|
* @param {Number} [options.wtimeout] sets a [timeout for the write concern](https://www.mongodb.com/docs/manual/reference/write-concern/#wtimeout). Overrides the [schema-level `writeConcern` option](https://mongoosejs.com/docs/guide.html#writeConcern).
|
|
522
533
|
* @param {Boolean} [options.checkKeys=true] the MongoDB driver prevents you from saving keys that start with '$' or contain '.' by default. Set this option to `false` to skip that check. See [restrictions on field names](https://docs.mongodb.com/manual/reference/limits/#mongodb-limit-Restrictions-on-Field-Names)
|
|
523
534
|
* @param {Boolean} [options.timestamps=true] if `false` and [timestamps](https://mongoosejs.com/docs/guide.html#timestamps) are enabled, skip timestamps for this `save()`.
|
|
535
|
+
* @param {Array} [options.pathsToSave] An array of paths that tell mongoose to only validate and save the paths in `pathsToSave`.
|
|
524
536
|
* @throws {DocumentNotFoundError} if this [save updates an existing document](https://mongoosejs.com/docs/api/document.html#Document.prototype.isNew) but the document doesn't exist in the database. For example, you will get this error if the document is [deleted between when you retrieved the document and when you saved it](documents.html#updating).
|
|
525
537
|
* @return {Promise}
|
|
526
538
|
* @api public
|
|
@@ -747,7 +759,6 @@ function handleAtomics(self, where, delta, data, value) {
|
|
|
747
759
|
|
|
748
760
|
Model.prototype.$__delta = function() {
|
|
749
761
|
const dirty = this.$__dirty();
|
|
750
|
-
|
|
751
762
|
const optimisticConcurrency = this.$__schema.options.optimisticConcurrency;
|
|
752
763
|
if (optimisticConcurrency) {
|
|
753
764
|
if (Array.isArray(optimisticConcurrency)) {
|
package/lib/query.js
CHANGED
|
@@ -2861,19 +2861,27 @@ Query.prototype.distinct = function(field, conditions) {
|
|
|
2861
2861
|
* Cannot be used with `distinct()`
|
|
2862
2862
|
*
|
|
2863
2863
|
* @param {Object|String|Array<Array<(string | number)>>} arg
|
|
2864
|
+
* @param {Object} [options]
|
|
2865
|
+
* @param {Boolean} [options.override=false] If true, replace existing sort options with `arg`
|
|
2864
2866
|
* @return {Query} this
|
|
2865
2867
|
* @see cursor.sort https://www.mongodb.com/docs/manual/reference/method/cursor.sort/
|
|
2866
2868
|
* @api public
|
|
2867
2869
|
*/
|
|
2868
2870
|
|
|
2869
|
-
Query.prototype.sort = function(arg) {
|
|
2870
|
-
if (arguments.length >
|
|
2871
|
-
throw new Error('sort()
|
|
2871
|
+
Query.prototype.sort = function(arg, options) {
|
|
2872
|
+
if (arguments.length > 2) {
|
|
2873
|
+
throw new Error('sort() takes at most 2 arguments');
|
|
2874
|
+
}
|
|
2875
|
+
if (options != null && typeof options !== 'object') {
|
|
2876
|
+
throw new Error('sort() options argument must be an object or nullish');
|
|
2872
2877
|
}
|
|
2873
2878
|
|
|
2874
2879
|
if (this.options.sort == null) {
|
|
2875
2880
|
this.options.sort = {};
|
|
2876
2881
|
}
|
|
2882
|
+
if (options && options.override) {
|
|
2883
|
+
this.options.sort = {};
|
|
2884
|
+
}
|
|
2877
2885
|
const sort = this.options.sort;
|
|
2878
2886
|
if (typeof arg === 'string') {
|
|
2879
2887
|
const properties = arg.indexOf(' ') === -1 ? [arg] : arg.split(' ');
|
|
@@ -279,7 +279,7 @@ SchemaDocumentArray.prototype.doValidate = function(array, fn, scope, options) {
|
|
|
279
279
|
continue;
|
|
280
280
|
}
|
|
281
281
|
|
|
282
|
-
doc.$__validate(callback);
|
|
282
|
+
doc.$__validate(null, options, callback);
|
|
283
283
|
}
|
|
284
284
|
}
|
|
285
285
|
};
|
|
@@ -330,7 +330,7 @@ SchemaDocumentArray.prototype.doValidateSync = function(array, scope, options) {
|
|
|
330
330
|
continue;
|
|
331
331
|
}
|
|
332
332
|
|
|
333
|
-
const subdocValidateError = doc.validateSync();
|
|
333
|
+
const subdocValidateError = doc.validateSync(options);
|
|
334
334
|
|
|
335
335
|
if (subdocValidateError && resultError == null) {
|
|
336
336
|
resultError = subdocValidateError;
|
package/lib/schema.js
CHANGED
|
@@ -1300,6 +1300,7 @@ Schema.prototype.interpretAsType = function(path, obj, options) {
|
|
|
1300
1300
|
return clone;
|
|
1301
1301
|
}
|
|
1302
1302
|
|
|
1303
|
+
|
|
1303
1304
|
// If this schema has an associated Mongoose object, use the Mongoose object's
|
|
1304
1305
|
// copy of SchemaTypes re: gh-7158 gh-6933
|
|
1305
1306
|
const MongooseTypes = this.base != null ? this.base.Schema.Types : Schema.Types;
|
|
@@ -1365,9 +1366,13 @@ Schema.prototype.interpretAsType = function(path, obj, options) {
|
|
|
1365
1366
|
}
|
|
1366
1367
|
return new MongooseTypes.DocumentArray(path, cast[options.typeKey], obj, cast);
|
|
1367
1368
|
}
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1369
|
+
if (typeof cast !== 'undefined') {
|
|
1370
|
+
if (Array.isArray(cast) || cast.type === Array || cast.type == 'Array') {
|
|
1371
|
+
if (cast && cast.type == 'Array') {
|
|
1372
|
+
cast.type = Array;
|
|
1373
|
+
}
|
|
1374
|
+
return new MongooseTypes.Array(path, this.interpretAsType(path, cast, options), obj);
|
|
1375
|
+
}
|
|
1371
1376
|
}
|
|
1372
1377
|
|
|
1373
1378
|
// Handle both `new Schema({ arr: [{ subpath: String }] })` and `new Schema({ arr: [{ type: { subpath: string } }] })`
|
|
@@ -1418,7 +1423,6 @@ Schema.prototype.interpretAsType = function(path, obj, options) {
|
|
|
1418
1423
|
type = cast[options.typeKey] && (options.typeKey !== 'type' || !cast.type.type)
|
|
1419
1424
|
? cast[options.typeKey]
|
|
1420
1425
|
: cast;
|
|
1421
|
-
|
|
1422
1426
|
if (Array.isArray(type)) {
|
|
1423
1427
|
return new MongooseTypes.Array(path, this.interpretAsType(path, type, options), obj);
|
|
1424
1428
|
}
|
package/lib/schemaType.js
CHANGED
|
@@ -803,6 +803,21 @@ SchemaType.prototype.get = function(fn) {
|
|
|
803
803
|
return this;
|
|
804
804
|
};
|
|
805
805
|
|
|
806
|
+
/**
|
|
807
|
+
* Adds multiple validators for this document path.
|
|
808
|
+
* Calls `validate()` for every element in validators.
|
|
809
|
+
*
|
|
810
|
+
* @param {Array<RegExp|Function|Object>} validators
|
|
811
|
+
* @returns this
|
|
812
|
+
*/
|
|
813
|
+
|
|
814
|
+
SchemaType.prototype.validateAll = function(validators) {
|
|
815
|
+
for (let i = 0; i < validators.length; i++) {
|
|
816
|
+
this.validate(validators[i]);
|
|
817
|
+
}
|
|
818
|
+
return this;
|
|
819
|
+
};
|
|
820
|
+
|
|
806
821
|
/**
|
|
807
822
|
* Adds validator(s) for this document path.
|
|
808
823
|
*
|
|
@@ -1285,6 +1300,9 @@ SchemaType.prototype.select = function select(val) {
|
|
|
1285
1300
|
SchemaType.prototype.doValidate = function(value, fn, scope, options) {
|
|
1286
1301
|
let err = false;
|
|
1287
1302
|
const path = this.path;
|
|
1303
|
+
if (typeof fn !== 'function') {
|
|
1304
|
+
throw new TypeError(`Must pass callback function to doValidate(), got ${typeof fn}`);
|
|
1305
|
+
}
|
|
1288
1306
|
|
|
1289
1307
|
// Avoid non-object `validators`
|
|
1290
1308
|
const validators = this.validators.
|
|
@@ -1419,7 +1437,6 @@ SchemaType.prototype.doValidateSync = function(value, scope, options) {
|
|
|
1419
1437
|
let i = 0;
|
|
1420
1438
|
const len = validators.length;
|
|
1421
1439
|
for (i = 0; i < len; ++i) {
|
|
1422
|
-
|
|
1423
1440
|
const v = validators[i];
|
|
1424
1441
|
|
|
1425
1442
|
if (v === null || typeof v !== 'object') {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongoose",
|
|
3
3
|
"description": "Mongoose MongoDB ODM",
|
|
4
|
-
"version": "8.
|
|
4
|
+
"version": "8.3.0",
|
|
5
5
|
"author": "Guillermo Rauch <guillermo@learnboost.com>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mongodb",
|
|
@@ -19,17 +19,17 @@
|
|
|
19
19
|
],
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"bson": "^6.
|
|
23
|
-
"kareem": "2.
|
|
24
|
-
"mongodb": "6.
|
|
22
|
+
"bson": "^6.5.0",
|
|
23
|
+
"kareem": "2.6.0",
|
|
24
|
+
"mongodb": "6.5.0",
|
|
25
25
|
"mpath": "0.9.0",
|
|
26
26
|
"mquery": "5.0.0",
|
|
27
27
|
"ms": "2.1.3",
|
|
28
28
|
"sift": "16.0.1"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@babel/core": "7.24.
|
|
32
|
-
"@babel/preset-env": "7.24.
|
|
31
|
+
"@babel/core": "7.24.3",
|
|
32
|
+
"@babel/preset-env": "7.24.3",
|
|
33
33
|
"@typescript-eslint/eslint-plugin": "^6.2.1",
|
|
34
34
|
"@typescript-eslint/parser": "^6.2.1",
|
|
35
35
|
"acquit": "1.3.0",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"dotenv": "16.4.5",
|
|
47
47
|
"dox": "1.0.0",
|
|
48
48
|
"eslint": "8.57.0",
|
|
49
|
-
"eslint-plugin-markdown": "^
|
|
49
|
+
"eslint-plugin-markdown": "^4.0.1",
|
|
50
50
|
"eslint-plugin-mocha-no-only": "1.1.1",
|
|
51
51
|
"express": "^4.18.1",
|
|
52
52
|
"fs-extra": "~11.2.0",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"markdownlint-cli2": "^0.12.1",
|
|
57
57
|
"marked": "4.3.0",
|
|
58
58
|
"mkdirp": "^3.0.1",
|
|
59
|
-
"mocha": "10.
|
|
59
|
+
"mocha": "10.4.0",
|
|
60
60
|
"moment": "2.x",
|
|
61
61
|
"mongodb-memory-server": "8.15.1",
|
|
62
62
|
"ncp": "^2.0.0",
|
|
@@ -65,10 +65,10 @@
|
|
|
65
65
|
"q": "1.5.1",
|
|
66
66
|
"sinon": "17.0.1",
|
|
67
67
|
"stream-browserify": "3.0.0",
|
|
68
|
-
"tsd": "0.
|
|
69
|
-
"typescript": "5.
|
|
68
|
+
"tsd": "0.31.0",
|
|
69
|
+
"typescript": "5.4.3",
|
|
70
70
|
"uuid": "9.0.1",
|
|
71
|
-
"webpack": "5.
|
|
71
|
+
"webpack": "5.91.0"
|
|
72
72
|
},
|
|
73
73
|
"directories": {
|
|
74
74
|
"lib": "./lib/mongoose"
|
package/types/index.d.ts
CHANGED
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
declare class NativeDate extends global.Date { }
|
|
28
28
|
|
|
29
29
|
declare module 'mongoose' {
|
|
30
|
+
import Kareem = require('kareem');
|
|
30
31
|
import events = require('events');
|
|
31
32
|
import mongodb = require('mongodb');
|
|
32
33
|
import mongoose = require('mongoose');
|
|
@@ -397,7 +398,6 @@ declare module 'mongoose' {
|
|
|
397
398
|
): this;
|
|
398
399
|
// this = Document
|
|
399
400
|
pre<T = THydratedDocumentType>(method: 'save', fn: PreSaveMiddlewareFunction<T>): this;
|
|
400
|
-
pre<T = THydratedDocumentType>(method: 'save', options: SchemaPreOptions, fn: PreSaveMiddlewareFunction<T>): this;
|
|
401
401
|
pre<T = THydratedDocumentType>(method: MongooseDistinctDocumentMiddleware|MongooseDistinctDocumentMiddleware[], fn: PreMiddlewareFunction<T>): this;
|
|
402
402
|
pre<T = THydratedDocumentType>(method: MongooseDistinctDocumentMiddleware|MongooseDistinctDocumentMiddleware[], options: SchemaPreOptions, fn: PreMiddlewareFunction<T>): this;
|
|
403
403
|
pre<T = THydratedDocumentType>(
|
|
@@ -415,7 +415,6 @@ declare module 'mongoose' {
|
|
|
415
415
|
pre<T = THydratedDocumentType|Query<any, any>>(method: MongooseQueryOrDocumentMiddleware | MongooseQueryOrDocumentMiddleware[] | RegExp, fn: PreMiddlewareFunction<T>): this;
|
|
416
416
|
// method aggregate
|
|
417
417
|
pre<T extends Aggregate<any>>(method: 'aggregate' | RegExp, fn: PreMiddlewareFunction<T>): this;
|
|
418
|
-
pre<T extends Aggregate<any>>(method: 'aggregate' | RegExp, options: SchemaPreOptions, fn: PreMiddlewareFunction<T>): this;
|
|
419
418
|
/* method insertMany */
|
|
420
419
|
pre<T = TModelType>(
|
|
421
420
|
method: 'insertMany' | RegExp,
|
|
@@ -426,16 +425,6 @@ declare module 'mongoose' {
|
|
|
426
425
|
options?: InsertManyOptions & { lean?: boolean }
|
|
427
426
|
) => void | Promise<void>
|
|
428
427
|
): this;
|
|
429
|
-
pre<T = TModelType>(
|
|
430
|
-
method: 'insertMany' | RegExp,
|
|
431
|
-
options: SchemaPreOptions,
|
|
432
|
-
fn: (
|
|
433
|
-
this: T,
|
|
434
|
-
next: (err?: CallbackError) => void,
|
|
435
|
-
docs: any | Array<any>,
|
|
436
|
-
options?: InsertManyOptions & { lean?: boolean }
|
|
437
|
-
) => void | Promise<void>
|
|
438
|
-
): this;
|
|
439
428
|
/* method bulkWrite */
|
|
440
429
|
pre<T = TModelType>(
|
|
441
430
|
method: 'bulkWrite' | RegExp,
|
|
@@ -446,16 +435,6 @@ declare module 'mongoose' {
|
|
|
446
435
|
options?: mongodb.BulkWriteOptions & MongooseBulkWriteOptions
|
|
447
436
|
) => void | Promise<void>
|
|
448
437
|
): this;
|
|
449
|
-
pre<T = TModelType>(
|
|
450
|
-
method: 'bulkWrite' | RegExp,
|
|
451
|
-
options: SchemaPreOptions,
|
|
452
|
-
fn: (
|
|
453
|
-
this: T,
|
|
454
|
-
next: (err?: CallbackError) => void,
|
|
455
|
-
ops: Array<mongodb.AnyBulkWriteOperation<any> & MongooseBulkWritePerWriteOptions>,
|
|
456
|
-
options?: mongodb.BulkWriteOptions & MongooseBulkWriteOptions
|
|
457
|
-
) => void | Promise<void>
|
|
458
|
-
): this;
|
|
459
438
|
/* method createCollection */
|
|
460
439
|
pre<T = TModelType>(
|
|
461
440
|
method: 'createCollection' | RegExp,
|
|
@@ -465,15 +444,6 @@ declare module 'mongoose' {
|
|
|
465
444
|
options?: mongodb.CreateCollectionOptions & Pick<SchemaOptions, 'expires'>
|
|
466
445
|
) => void | Promise<void>
|
|
467
446
|
): this;
|
|
468
|
-
pre<T = TModelType>(
|
|
469
|
-
method: 'createCollection' | RegExp,
|
|
470
|
-
options: SchemaPreOptions,
|
|
471
|
-
fn: (
|
|
472
|
-
this: T,
|
|
473
|
-
next: (err?: CallbackError) => void,
|
|
474
|
-
options?: mongodb.CreateCollectionOptions & Pick<SchemaOptions, 'expires'>
|
|
475
|
-
) => void | Promise<void>
|
|
476
|
-
): this;
|
|
477
447
|
|
|
478
448
|
/** Object of currently defined query helpers on this schema. */
|
|
479
449
|
query: TQueryHelpers;
|
|
@@ -722,5 +692,9 @@ declare module 'mongoose' {
|
|
|
722
692
|
/* for ts-mongoose */
|
|
723
693
|
export class mquery { }
|
|
724
694
|
|
|
695
|
+
export function overwriteMiddlewareResult(val: any): Kareem.OverwriteMiddlewareResult;
|
|
696
|
+
|
|
697
|
+
export function skipMiddlewareFunction(val: any): Kareem.SkipWrappedFunction;
|
|
698
|
+
|
|
725
699
|
export default mongoose;
|
|
726
700
|
}
|
package/types/middlewares.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
declare module 'mongoose' {
|
|
2
|
+
import Kareem = require('kareem');
|
|
2
3
|
|
|
3
4
|
type MongooseQueryAndDocumentMiddleware = 'updateOne' | 'deleteOne';
|
|
4
5
|
|
|
@@ -37,13 +38,13 @@ declare module 'mongoose' {
|
|
|
37
38
|
this: ThisType,
|
|
38
39
|
next: CallbackWithoutResultAndOptionalError,
|
|
39
40
|
opts?: Record<string, any>
|
|
40
|
-
) => void | Promise<void
|
|
41
|
+
) => void | Promise<void> | Kareem.SkipWrappedFunction;
|
|
41
42
|
type PreSaveMiddlewareFunction<ThisType = any> = (
|
|
42
43
|
this: ThisType,
|
|
43
44
|
next: CallbackWithoutResultAndOptionalError,
|
|
44
45
|
opts: SaveOptions
|
|
45
|
-
) => void | Promise<void
|
|
46
|
-
type PostMiddlewareFunction<ThisType = any, ResType = any> = (this: ThisType, res: ResType, next: CallbackWithoutResultAndOptionalError) => void | Promise<void
|
|
46
|
+
) => void | Promise<void> | Kareem.SkipWrappedFunction;
|
|
47
|
+
type PostMiddlewareFunction<ThisType = any, ResType = any> = (this: ThisType, res: ResType, next: CallbackWithoutResultAndOptionalError) => void | Promise<void> | Kareem.OverwriteMiddlewareResult;
|
|
47
48
|
type ErrorHandlingMiddlewareFunction<ThisType = any, ResType = any> = (this: ThisType, err: NativeError, res: ResType, next: CallbackWithoutResultAndOptionalError) => void;
|
|
48
|
-
type ErrorHandlingMiddlewareWithOption<ThisType = any, ResType = any> = (this: ThisType, err: NativeError, res: ResType | null, next: CallbackWithoutResultAndOptionalError) => void | Promise<void
|
|
49
|
+
type ErrorHandlingMiddlewareWithOption<ThisType = any, ResType = any> = (this: ThisType, err: NativeError, res: ResType | null, next: CallbackWithoutResultAndOptionalError) => void | Promise<void> | Kareem.OverwriteMiddlewareResult;
|
|
49
50
|
}
|
package/types/query.d.ts
CHANGED
|
@@ -741,7 +741,10 @@ declare module 'mongoose' {
|
|
|
741
741
|
slice(val: number | Array<number>): this;
|
|
742
742
|
|
|
743
743
|
/** Sets the sort order. If an object is passed, values allowed are `asc`, `desc`, `ascending`, `descending`, `1`, and `-1`. */
|
|
744
|
-
sort(
|
|
744
|
+
sort(
|
|
745
|
+
arg?: string | { [key: string]: SortOrder | { $meta: any } } | [string, SortOrder][] | undefined | null,
|
|
746
|
+
options?: { override?: boolean }
|
|
747
|
+
): this;
|
|
745
748
|
|
|
746
749
|
/** Sets the tailable option (for use with capped collections). */
|
|
747
750
|
tailable(bool?: boolean, opts?: {
|
package/types/schematypes.d.ts
CHANGED
|
@@ -192,10 +192,14 @@ declare module 'mongoose' {
|
|
|
192
192
|
[other: string]: any;
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
-
interface Validator {
|
|
196
|
-
message?: string;
|
|
195
|
+
interface Validator<DocType = any> {
|
|
196
|
+
message?: string;
|
|
197
|
+
type?: string;
|
|
198
|
+
validator?: ValidatorFunction<DocType>;
|
|
197
199
|
}
|
|
198
200
|
|
|
201
|
+
type ValidatorFunction<DocType = any> = (this: DocType, value: any, validatorProperties?: Validator) => any;
|
|
202
|
+
|
|
199
203
|
class SchemaType<T = any, DocType = any> {
|
|
200
204
|
/** SchemaType constructor */
|
|
201
205
|
constructor(path: string, options?: AnyObject, instance?: string);
|
|
@@ -281,7 +285,10 @@ declare module 'mongoose' {
|
|
|
281
285
|
validators: Validator[];
|
|
282
286
|
|
|
283
287
|
/** Adds validator(s) for this document path. */
|
|
284
|
-
validate(obj: RegExp |
|
|
288
|
+
validate(obj: RegExp | ValidatorFunction<DocType> | Validator<DocType>, errorMsg?: string, type?: string): this;
|
|
289
|
+
|
|
290
|
+
/** Adds multiple validators for this document path. */
|
|
291
|
+
validateAll(validators: Array<RegExp | ValidatorFunction<DocType> | Validator<DocType>>): this;
|
|
285
292
|
|
|
286
293
|
/** Default options for this SchemaType */
|
|
287
294
|
defaultOptions?: Record<string, any>;
|