diff --git a/packages/minimongo/minimongo_tests.js b/packages/minimongo/minimongo_tests.js index 6a800c2f7d..75c26b8731 100644 --- a/packages/minimongo/minimongo_tests.js +++ b/packages/minimongo/minimongo_tests.js @@ -2881,6 +2881,25 @@ Tinytest.add("minimongo - modify", function (test) { { $setOnInsert: { a: 123 } }, { a: 123 }, ); + const testDate = new Date('2017-01-01'); + upsert( + { someDate: testDate }, + { $setOnInsert: { a: 123 } }, + { someDate: testDate, a: 123 }, + ); + upsert( + { + a: Object.create(null, { + $exists: { + writable: true, + configurable: true, + value: true + } + }), + }, + { $setOnInsert: { a: 123 } }, + { a: 123 }, + ); exception({}, {$set: {_id: 'bad'}}); diff --git a/packages/minimongo/selector.js b/packages/minimongo/selector.js index 15fb94d61b..02a702fb10 100644 --- a/packages/minimongo/selector.js +++ b/packages/minimongo/selector.js @@ -1251,19 +1251,22 @@ LocalCollection._f = { } }; -// Oddball function used by upsert. Make sure that when we're removing -// $ operators we don't accidently remove the "oid" (MongoID.ObjectID) -// EJSON type (which includes $type and $value properties). -LocalCollection._removeDollarOperators = function (selector) { - return EJSON.parse( - JSON.stringify( - EJSON.toJSONValue(selector), - function (key, value) { - if (EJSON.fromJSONValue(this) instanceof MongoID.ObjectID - || !key.startsWith("$")) { - return value; - } +// Oddball function used by upsert. +LocalCollection._removeDollarOperators = (selector) => { + const cleansed = {}; + + Object.keys(selector).forEach((key) => { + const value = selector[key]; + if (key.charAt(0) !== '$') { + if (value !== null + && value.constructor + && value.constructor.prototype === Object.prototype) { + cleansed[key] = LocalCollection._removeDollarOperators(value); + } else { + cleansed[key] = value; } - ) - ); + } + }); + + return cleansed; };