mongoose 5.0.2 → 5.0.6
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/CONTRIBUTING.md +29 -0
- package/History.md +46 -0
- package/lib/aggregate.js +2 -2
- package/lib/cast.js +6 -2
- package/lib/collection.js +6 -3
- package/lib/connection.js +10 -7
- package/lib/document.js +128 -84
- package/lib/drivers/node-mongodb-native/collection.js +1 -1
- package/lib/index.js +1 -0
- package/lib/model.js +11 -11
- package/lib/schema/array.js +18 -0
- package/lib/schema/objectid.js +8 -7
- package/lib/schema.js +8 -4
- package/lib/schematype.js +2 -2
- package/lib/services/model/discriminator.js +1 -1
- package/lib/services/projection/isExclusive.js +28 -0
- package/lib/services/query/castUpdate.js +14 -11
- package/lib/types/array.js +8 -4
- package/lib/types/embedded.js +2 -2
- package/lib/types/subdocument.js +1 -1
- package/lib/utils.js +27 -8
- package/package.json +5 -5
- package/docs.html +0 -413
- package/test.js +0 -1
package/lib/schema.js
CHANGED
|
@@ -122,16 +122,20 @@ function aliasFields(schema) {
|
|
|
122
122
|
|
|
123
123
|
if (alias) {
|
|
124
124
|
if ('string' === typeof alias && alias.length > 0) {
|
|
125
|
-
if (schema.aliases[alias])
|
|
125
|
+
if (schema.aliases[alias]) {
|
|
126
126
|
throw new Error('Duplicate alias, alias ' + alias + ' is used more than once');
|
|
127
|
-
else
|
|
127
|
+
} else {
|
|
128
128
|
schema.aliases[alias] = prop;
|
|
129
|
+
}
|
|
129
130
|
|
|
130
131
|
schema
|
|
131
132
|
.virtual(alias)
|
|
132
133
|
.get((function(p) {
|
|
133
134
|
return function() {
|
|
134
|
-
|
|
135
|
+
if (typeof this.get === 'function') {
|
|
136
|
+
return this.get(p);
|
|
137
|
+
}
|
|
138
|
+
return this[p];
|
|
135
139
|
};
|
|
136
140
|
})(prop))
|
|
137
141
|
.set((function(p) {
|
|
@@ -231,7 +235,6 @@ Schema.prototype.tree;
|
|
|
231
235
|
|
|
232
236
|
Schema.prototype.clone = function() {
|
|
233
237
|
var s = new Schema(this.paths, this.options);
|
|
234
|
-
// Clone the call queue
|
|
235
238
|
var cloneOpts = {};
|
|
236
239
|
s.callQueue = this.callQueue.map(function(f) { return f; });
|
|
237
240
|
s.methods = utils.clone(this.methods, cloneOpts);
|
|
@@ -240,6 +243,7 @@ Schema.prototype.clone = function() {
|
|
|
240
243
|
s.plugins = Array.prototype.slice.call(this.plugins);
|
|
241
244
|
s._indexes = utils.clone(this._indexes, cloneOpts);
|
|
242
245
|
s.s.hooks = this.s.hooks.clone();
|
|
246
|
+
s.virtuals = utils.clone(this.virtuals, cloneOpts);
|
|
243
247
|
return s;
|
|
244
248
|
};
|
|
245
249
|
|
package/lib/schematype.js
CHANGED
|
@@ -773,7 +773,7 @@ SchemaType.prototype.doValidate = function(value, fn, scope) {
|
|
|
773
773
|
}
|
|
774
774
|
if (ok === undefined || ok) {
|
|
775
775
|
if (--count <= 0) {
|
|
776
|
-
|
|
776
|
+
utils.immediate(function() {
|
|
777
777
|
fn(null);
|
|
778
778
|
});
|
|
779
779
|
}
|
|
@@ -781,7 +781,7 @@ SchemaType.prototype.doValidate = function(value, fn, scope) {
|
|
|
781
781
|
var ErrorConstructor = validatorProperties.ErrorConstructor || ValidatorError;
|
|
782
782
|
err = new ErrorConstructor(validatorProperties);
|
|
783
783
|
err.$isValidatorError = true;
|
|
784
|
-
|
|
784
|
+
utils.immediate(function() {
|
|
785
785
|
fn(err);
|
|
786
786
|
});
|
|
787
787
|
}
|
|
@@ -55,7 +55,7 @@ module.exports = function discriminator(model, name, schema) {
|
|
|
55
55
|
delete schema.paths._id;
|
|
56
56
|
delete schema.tree._id;
|
|
57
57
|
}
|
|
58
|
-
utils.merge(schema, baseSchema);
|
|
58
|
+
utils.merge(schema, baseSchema, { omit: { discriminators: true } });
|
|
59
59
|
|
|
60
60
|
var obj = {};
|
|
61
61
|
obj[key] = {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const isDefiningProjection = require('./isDefiningProjection');
|
|
4
|
+
|
|
5
|
+
/*!
|
|
6
|
+
* ignore
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
module.exports = function isExclusive(projection) {
|
|
10
|
+
let keys = Object.keys(projection);
|
|
11
|
+
let ki = keys.length;
|
|
12
|
+
let exclude = null;
|
|
13
|
+
|
|
14
|
+
if (ki === 1 && keys[0] === '_id') {
|
|
15
|
+
exclude = !!projection[keys[ki]];
|
|
16
|
+
} else {
|
|
17
|
+
while (ki--) {
|
|
18
|
+
// Does this projection explicitly define inclusion/exclusion?
|
|
19
|
+
// Explicitly avoid `$meta` and `$slice`
|
|
20
|
+
if (keys[ki] !== '_id' && isDefiningProjection(projection[keys[ki]])) {
|
|
21
|
+
exclude = !projection[keys[ki]];
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return exclude;
|
|
28
|
+
};
|
|
@@ -66,8 +66,10 @@ module.exports = function castUpdate(schema, obj, options, context) {
|
|
|
66
66
|
op = ops[i];
|
|
67
67
|
val = ret[op];
|
|
68
68
|
hasDollarKey = hasDollarKey || op.charAt(0) === '$';
|
|
69
|
+
|
|
69
70
|
if (val &&
|
|
70
71
|
typeof val === 'object' &&
|
|
72
|
+
!Buffer.isBuffer(val) &&
|
|
71
73
|
(!overwrite || hasDollarKey)) {
|
|
72
74
|
hasKeys |= walkUpdatePath(schema, val, op, options.strict, context);
|
|
73
75
|
} else if (overwrite && ret && typeof ret === 'object') {
|
|
@@ -111,8 +113,7 @@ function walkUpdatePath(schema, obj, op, strict, context, pref) {
|
|
|
111
113
|
var key;
|
|
112
114
|
var val;
|
|
113
115
|
|
|
114
|
-
var
|
|
115
|
-
var aggregatedError = new ValidationError();
|
|
116
|
+
var aggregatedError = null;
|
|
116
117
|
|
|
117
118
|
var useNestedStrict = schema.options.useNestedStrict;
|
|
118
119
|
|
|
@@ -133,8 +134,7 @@ function walkUpdatePath(schema, obj, op, strict, context, pref) {
|
|
|
133
134
|
$each: castUpdateVal(schematype, val.$each, op, context)
|
|
134
135
|
};
|
|
135
136
|
} catch (error) {
|
|
136
|
-
|
|
137
|
-
_handleCastError(error, context, key, aggregatedError);
|
|
137
|
+
aggregatedError = _handleCastError(error, context, key, aggregatedError);
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
if (val.$slice != null) {
|
|
@@ -152,8 +152,7 @@ function walkUpdatePath(schema, obj, op, strict, context, pref) {
|
|
|
152
152
|
try {
|
|
153
153
|
obj[key] = castUpdateVal(schematype, val, op, context);
|
|
154
154
|
} catch (error) {
|
|
155
|
-
|
|
156
|
-
_handleCastError(error, context, key, aggregatedError);
|
|
155
|
+
aggregatedError = _handleCastError(error, context, key, aggregatedError);
|
|
157
156
|
}
|
|
158
157
|
}
|
|
159
158
|
} else if ((op === '$currentDate') || (op in castOps && schematype)) {
|
|
@@ -161,8 +160,7 @@ function walkUpdatePath(schema, obj, op, strict, context, pref) {
|
|
|
161
160
|
try {
|
|
162
161
|
obj[key] = castUpdateVal(schematype, val, op, context);
|
|
163
162
|
} catch (error) {
|
|
164
|
-
|
|
165
|
-
_handleCastError(error, context, key, aggregatedError);
|
|
163
|
+
aggregatedError = _handleCastError(error, context, key, aggregatedError);
|
|
166
164
|
}
|
|
167
165
|
|
|
168
166
|
hasKeys = true;
|
|
@@ -228,14 +226,17 @@ function walkUpdatePath(schema, obj, op, strict, context, pref) {
|
|
|
228
226
|
try {
|
|
229
227
|
obj[key] = castUpdateVal(schematype, val, op, key, context);
|
|
230
228
|
} catch (error) {
|
|
231
|
-
|
|
232
|
-
|
|
229
|
+
aggregatedError = _handleCastError(error, context, key, aggregatedError);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (Array.isArray(obj[key]) && (op === '$addToSet' || op === '$push') && key !== '$each') {
|
|
233
|
+
obj[key] = { $each: obj[key] };
|
|
233
234
|
}
|
|
234
235
|
}
|
|
235
236
|
}
|
|
236
237
|
}
|
|
237
238
|
|
|
238
|
-
if (
|
|
239
|
+
if (aggregatedError != null) {
|
|
239
240
|
throw aggregatedError;
|
|
240
241
|
}
|
|
241
242
|
|
|
@@ -250,7 +251,9 @@ function _handleCastError(error, query, key, aggregatedError) {
|
|
|
250
251
|
if (typeof query !== 'object' || !query.options.multipleCastError) {
|
|
251
252
|
throw error;
|
|
252
253
|
}
|
|
254
|
+
aggregatedError = aggregatedError || new ValidationError();
|
|
253
255
|
aggregatedError.addError(key, error);
|
|
256
|
+
return aggregatedError;
|
|
254
257
|
}
|
|
255
258
|
|
|
256
259
|
/*!
|
package/lib/types/array.js
CHANGED
|
@@ -9,7 +9,7 @@ const cleanModifiedSubpaths = require('../services/document/cleanModifiedSubpath
|
|
|
9
9
|
const internalToObjectOptions = require('../options').internalToObjectOptions;
|
|
10
10
|
const utils = require('../utils');
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
const isMongooseObject = utils.isMongooseObject;
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Mongoose Array constructor.
|
|
@@ -237,8 +237,10 @@ MongooseArray.mixin = {
|
|
|
237
237
|
var keys = Object.keys(this._atomics);
|
|
238
238
|
var i = keys.length;
|
|
239
239
|
|
|
240
|
+
const opts = Object.assign({}, internalToObjectOptions, { _isNested: true });
|
|
241
|
+
|
|
240
242
|
if (i === 0) {
|
|
241
|
-
ret[0] = ['$set', this.toObject(
|
|
243
|
+
ret[0] = ['$set', this.toObject(opts)];
|
|
242
244
|
return ret;
|
|
243
245
|
}
|
|
244
246
|
|
|
@@ -250,9 +252,11 @@ MongooseArray.mixin = {
|
|
|
250
252
|
// need to convert their elements as if they were MongooseArrays
|
|
251
253
|
// to handle populated arrays versus DocumentArrays properly.
|
|
252
254
|
if (isMongooseObject(val)) {
|
|
253
|
-
val = val.toObject(
|
|
255
|
+
val = val.toObject(opts);
|
|
254
256
|
} else if (Array.isArray(val)) {
|
|
255
|
-
val = this.toObject.call(val,
|
|
257
|
+
val = this.toObject.call(val, opts);
|
|
258
|
+
} else if (val != null && Array.isArray(val.$each)) {
|
|
259
|
+
val.$each = this.toObject.call(val.$each, opts);
|
|
256
260
|
} else if (val.valueOf) {
|
|
257
261
|
val = val.valueOf();
|
|
258
262
|
}
|
package/lib/types/embedded.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
const Document = require('../document_provider')();
|
|
8
8
|
const EventEmitter = require('events').EventEmitter;
|
|
9
|
-
|
|
9
|
+
const internalToObjectOptions = require('../options').internalToObjectOptions;
|
|
10
10
|
const utils = require('../utils');
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -126,7 +126,7 @@ EmbeddedDocument.prototype.save = function(fn) {
|
|
|
126
126
|
*/
|
|
127
127
|
|
|
128
128
|
EmbeddedDocument.prototype.$__save = function(fn) {
|
|
129
|
-
return
|
|
129
|
+
return utils.immediate(() => fn(null, this));
|
|
130
130
|
};
|
|
131
131
|
|
|
132
132
|
/*!
|
package/lib/types/subdocument.js
CHANGED
package/lib/utils.js
CHANGED
|
@@ -210,7 +210,7 @@ exports.promiseOrCallback = function promiseOrCallback(callback, fn) {
|
|
|
210
210
|
try {
|
|
211
211
|
return fn(callback);
|
|
212
212
|
} catch (error) {
|
|
213
|
-
return
|
|
213
|
+
return process.nextTick(() => {
|
|
214
214
|
throw error;
|
|
215
215
|
});
|
|
216
216
|
}
|
|
@@ -316,9 +316,15 @@ exports.merge = function merge(to, from, options) {
|
|
|
316
316
|
|
|
317
317
|
while (i < len) {
|
|
318
318
|
key = keys[i++];
|
|
319
|
+
if (options.omit && options.omit[key]) {
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
319
322
|
if (to[key] == null) {
|
|
320
323
|
to[key] = from[key];
|
|
321
324
|
} else if (exports.isObject(from[key])) {
|
|
325
|
+
if (!exports.isObject(to[key])) {
|
|
326
|
+
to[key] = {};
|
|
327
|
+
}
|
|
322
328
|
merge(to[key], from[key], options);
|
|
323
329
|
} else if (options.overwrite) {
|
|
324
330
|
to[key] = from[key];
|
|
@@ -756,9 +762,13 @@ exports.mergeClone = function(to, fromObj) {
|
|
|
756
762
|
flattenDecimals: false
|
|
757
763
|
});
|
|
758
764
|
} else {
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
765
|
+
var val = fromObj[key];
|
|
766
|
+
if (val != null && val.valueOf) {
|
|
767
|
+
val = val.valueOf();
|
|
768
|
+
}
|
|
769
|
+
if (exports.isObject(val)) {
|
|
770
|
+
var obj = val;
|
|
771
|
+
if (isMongooseObject(val) && !val.isMongooseBuffer) {
|
|
762
772
|
obj = obj.toObject({
|
|
763
773
|
transform: false,
|
|
764
774
|
virtuals: false,
|
|
@@ -767,14 +777,12 @@ exports.mergeClone = function(to, fromObj) {
|
|
|
767
777
|
flattenDecimals: false
|
|
768
778
|
});
|
|
769
779
|
}
|
|
770
|
-
if (
|
|
780
|
+
if (val.isMongooseBuffer) {
|
|
771
781
|
obj = new Buffer(obj);
|
|
772
782
|
}
|
|
773
783
|
exports.mergeClone(to[key], obj);
|
|
774
784
|
} else {
|
|
775
|
-
|
|
776
|
-
// $each operator in mongodb 2.4.4
|
|
777
|
-
to[key] = exports.clone(fromObj[key], {
|
|
785
|
+
to[key] = exports.clone(val, {
|
|
778
786
|
flattenDecimals: false
|
|
779
787
|
});
|
|
780
788
|
}
|
|
@@ -796,6 +804,17 @@ exports.each = function(arr, fn) {
|
|
|
796
804
|
}
|
|
797
805
|
};
|
|
798
806
|
|
|
807
|
+
/*!
|
|
808
|
+
* Centralize this so we can more easily work around issues with people
|
|
809
|
+
* stubbing out `process.nextTick()` in tests using sinon:
|
|
810
|
+
* https://github.com/sinonjs/lolex#automatically-incrementing-mocked-time
|
|
811
|
+
* See gh-6074
|
|
812
|
+
*/
|
|
813
|
+
|
|
814
|
+
exports.immediate = function immediate(cb) {
|
|
815
|
+
return process.nextTick(cb);
|
|
816
|
+
};
|
|
817
|
+
|
|
799
818
|
/*!
|
|
800
819
|
* ignore
|
|
801
820
|
*/
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongoose",
|
|
3
3
|
"description": "Mongoose MongoDB ODM",
|
|
4
|
-
"version": "5.0.
|
|
4
|
+
"version": "5.0.6",
|
|
5
5
|
"author": "Guillermo Rauch <guillermo@learnboost.com>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mongodb",
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"async": "2.1.4",
|
|
23
23
|
"bson": "~1.0.4",
|
|
24
|
-
"kareem": "2.0.
|
|
24
|
+
"kareem": "2.0.4",
|
|
25
25
|
"lodash.get": "4.4.2",
|
|
26
|
-
"mongodb": "3.0.
|
|
27
|
-
"mongoose-legacy-pluralize": "1.0.
|
|
26
|
+
"mongodb": "3.0.2",
|
|
27
|
+
"mongoose-legacy-pluralize": "1.0.2",
|
|
28
28
|
"mpath": "0.3.0",
|
|
29
29
|
"mquery": "3.0.0",
|
|
30
30
|
"ms": "2.0.0",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"lint": "eslint . --quiet",
|
|
66
66
|
"nsp": "nsp check",
|
|
67
67
|
"release": "git push origin master --tags && npm publish",
|
|
68
|
-
"release-legacy": "git push origin 4.x --tags && npm publish --tag
|
|
68
|
+
"release-legacy": "git push origin 4.x --tags && npm publish --tag legacy",
|
|
69
69
|
"test": "mocha --exit test/*.test.js test/**/*.test.js",
|
|
70
70
|
"test-cov": "nyc --reporter=html --reporter=text npm test"
|
|
71
71
|
},
|