diff --git a/History.md b/History.md index 2e1d6500294..91130da0e10 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,16 @@ +5.11.15 / 2021-02-03 +==================== + * fix(document): fix issues with `isSelected` as an path in a nested schema #9884 #9873 [IslandRhythms](https://github.com/IslandRhythms) + * fix(index.d.ts): better support for `SchemaDefinition` generics when creating schema #9863 #9862 #9789 + * fix(index.d.ts): allow required function in array definition #9888 [Ugzuzg](https://github.com/Ugzuzg) + * fix(index.d.ts): reorder create typings to allow array desctructuring #9890 [Ugzuzg](https://github.com/Ugzuzg) + * fix(index.d.ts): add missing overload to Model.validate #9878 #9877 [jonamat](https://github.com/jonamat) + * fix(index.d.ts): throw compiler error if schema says path is a String, but interface says path is a number #9857 + * fix(index.d.ts): make `Query` a class, allow calling `Query#where()` with object argument and with no arguments #9856 + * fix(index.d.ts): support calling `Schema#pre()` and `Schema#post()` with options and array of hooked function names #9844 + * docs(faq): mention other debug options than console #9887 [dandv](https://github.com/dandv) + * docs(connections): clarify that Mongoose can emit 'error' both during initial connection and after initial connection #9853 + 5.11.14 / 2021-01-28 ==================== * fix(populate): avoid inferring `justOne` from parent when populating a POJO with a manually populated path #9833 [IslandRhythms](https://github.com/IslandRhythms) diff --git a/docs/faq.pug b/docs/faq.pug index 54a6636b21d..29ef6affbd2 100644 --- a/docs/faq.pug +++ b/docs/faq.pug @@ -293,9 +293,10 @@ block content **Q**. How can I enable debugging? - **A**. Set the `debug` option to `true`: + **A**. Set the `debug` option: ```javascript + // all executed methods log output to console mongoose.set('debug', true) // disable colors in debug mode @@ -305,8 +306,7 @@ block content mongoose.set('debug', { shell: true }) ``` - All executed collection methods will log output of their arguments to your - console. + For more debugging options (streams, callbacks), see the ['debug' option under `.set()`](./api.html#mongoose_Mongoose-set).
diff --git a/index.d.ts b/index.d.ts index ff2b9c49019..e349d0cd652 100644 --- a/index.d.ts +++ b/index.d.ts @@ -630,11 +630,11 @@ declare module 'mongoose' { countDocuments(filter: FilterQuery, callback?: (err: any, count: number) => void): Query; /** Creates a new document or documents */ - create>(doc: DocContents): Promise; create>(docs: DocContents[], options?: SaveOptions): Promise; + create>(doc: DocContents): Promise; create>(...docs: DocContents[]): Promise; - create>(doc: DocContents, callback: (err: CallbackError, doc: T) => void): void; create>(docs: DocContents[], callback: (err: CallbackError, docs: T[]) => void): void; + create>(doc: DocContents, callback: (err: CallbackError, doc: T) => void): void; /** * Create the collection for this model. By default, if no indexes are specified, @@ -1382,7 +1382,7 @@ declare module 'mongoose' { * path cannot be set to a nullish value. If a function, Mongoose calls the * function and only checks for nullish values if the function returns a truthy value. */ - required?: boolean | (() => boolean) | [boolean, string]; + required?: boolean | (() => boolean) | [boolean, string] | [() => boolean, string]; /** * The default value for this path. If a function, Mongoose executes the function diff --git a/lib/document.js b/lib/document.js index 6c14f869db2..042b48ed342 100644 --- a/lib/document.js +++ b/lib/document.js @@ -140,7 +140,6 @@ function Document(obj, fields, skipId, options) { }); } } - if (obj) { // Skip set hooks if (this.$__original_set) { @@ -899,6 +898,7 @@ Document.prototype.overwrite = function overwrite(obj) { */ Document.prototype.$set = function $set(path, val, type, options) { + if (utils.isPOJO(type)) { options = type; type = undefined; @@ -937,9 +937,13 @@ Document.prototype.$set = function $set(path, val, type, options) { path = path._doc; } } + if (path == null) { + const _ = path; + path = val; + val = _; + } prefix = val ? val + '.' : ''; - keys = Object.keys(path); const len = keys.length; diff --git a/lib/query.js b/lib/query.js index b115e6f17f7..21e19d205ed 100644 --- a/lib/query.js +++ b/lib/query.js @@ -1397,9 +1397,11 @@ Query.prototype.setOptions = function(options, overwrite) { Query.prototype.explain = function(verbose) { if (arguments.length === 0) { this.options.explain = true; - return this; + } else if (verbose === false) { + delete this.options.explain; + } else { + this.options.explain = verbose; } - this.options.explain = verbose; return this; }; diff --git a/package.json b/package.json index 64ef253ecd8..2c62532081a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "mongoose", "description": "Mongoose MongoDB ODM", - "version": "5.11.14", + "version": "5.11.15", "author": "Guillermo Rauch ", "keywords": [ "mongodb", @@ -22,7 +22,7 @@ "@types/mongodb": "^3.5.27", "bson": "^1.1.4", "kareem": "2.3.2", - "mongodb": "3.6.3", + "mongodb": "3.6.4", "mongoose-legacy-pluralize": "1.0.2", "mpath": "0.8.3", "mquery": "3.2.3", diff --git a/test/document.test.js b/test/document.test.js index 6a9c50c13c1..dec8f31dc2f 100644 --- a/test/document.test.js +++ b/test/document.test.js @@ -9931,6 +9931,7 @@ describe('document', function() { assert.ok(doc); }); }); + it('Makes sure pre remove hook is executed gh-9885', function() { const SubSchema = new Schema({ myValue: { @@ -9968,5 +9969,47 @@ describe('document', function() { }); assert.equal(count, 1); }); + }); + + it('gh9880', function(done) { + const testSchema = new Schema({ + prop: String, + nestedProp: { + prop: String + } + }); + const Test = db.model('Test', testSchema); + + new Test({ + prop: 'Test', + nestedProp: null + }).save((err, doc) => { + doc.id; + doc.nestedProp; + + // let's clone this document: + new Test({ + prop: 'Test 2', + nestedProp: doc.nestedProp + }); + + Test.updateOne({ + _id: doc._id + }, { + nestedProp: null + }, (err) => { + assert.ifError(err); + Test.findOne({ + _id: doc._id + }, (err, updatedDoc) => { + assert.ifError(err); + new Test({ + prop: 'Test 3', + nestedProp: updatedDoc.nestedProp + }); + done(); + }); + }); + }); }); }); diff --git a/test/errors.validation.test.js b/test/errors.validation.test.js index 34c9c9f7127..69a32d020e3 100644 --- a/test/errors.validation.test.js +++ b/test/errors.validation.test.js @@ -243,16 +243,17 @@ describe('ValidationError', function() { }); describe('when user code defines a r/o Error#toJSON', function() { - it('shoud not fail', function() { + it('shoud not fail', function(done) { const err = []; const child = require('child_process') - .fork('./test/isolated/project-has-error.toJSON.js', { silent: true }); + .fork('./test/isolated/project-has-error.toJSON.js', ['--no-warnings'], { silent: true }); child.stderr.on('data', function(buf) { err.push(buf); }); child.on('exit', function(code) { const stderr = err.join(''); assert.equal(stderr, ''); assert.equal(code, 0); + done(); }); }); }); diff --git a/test/model.populate.test.js b/test/model.populate.test.js index def9145cde2..97871f1ac92 100644 --- a/test/model.populate.test.js +++ b/test/model.populate.test.js @@ -9870,7 +9870,6 @@ describe('model: populate:', function() { }); }); it('gh-9833', function() { - const util = require('util'); const Books = db.model('books', new Schema({ name: String, tags: [{ type: Schema.Types.ObjectId, ref: 'tags' }] })); const Tags = db.model('tags', new Schema({ author: Schema.Types.ObjectId })); const Authors = db.model('authors', new Schema({ name: String })); @@ -9898,8 +9897,6 @@ describe('model: populate:', function() { ]; const books = yield Books.aggregate(aggregateOptions).exec(); - console.log('books = ' + util.inspect(books, false, null, true)); - const populateOptions = [{ path: 'tags.author', model: 'authors', @@ -9907,7 +9904,6 @@ describe('model: populate:', function() { }]; const populatedBooks = yield Books.populate(books, populateOptions); - console.log('populatedBooks = ' + util.inspect(populatedBooks, false, null, true)); assert.ok(!Array.isArray(populatedBooks[0].tags[0].author)); }); }); diff --git a/test/typescript/create.ts b/test/typescript/create.ts index c20f56cc308..cb76ce45172 100644 --- a/test/typescript/create.ts +++ b/test/typescript/create.ts @@ -18,4 +18,11 @@ Test.create({ name: 'test' }, { name: 'test2' }).then((docs: ITest[]) => console Test.insertMany({ name: 'test' }).then((doc: ITest) => console.log(doc.name)); Test.insertMany([{ name: 'test' }], { session: null }).then((docs: ITest[]) => console.log(docs[0].name)); -Test.create([{ name: 'test' }], { validateBeforeSave: true }).then((docs: ITest[]) => console.log(docs[0].name)); \ No newline at end of file +Test.create([{ name: 'test' }], { validateBeforeSave: true }).then((docs: ITest[]) => console.log(docs[0].name)); + +(async() => { + const [t1] = await Test.create([{ name: 'test' }]); + const [t2, t3, t4] = await Test.create({ name: 'test' }, { name: 'test' }, { name: 'test' }); + (await Test.create([{ name: 'test' }]))[0]; + (await Test.create({ name: 'test' }))._id; +})(); diff --git a/test/typescript/schema.ts b/test/typescript/schema.ts index c6f61667b95..4aed0505b31 100644 --- a/test/typescript/schema.ts +++ b/test/typescript/schema.ts @@ -23,6 +23,15 @@ const movieSchema: Schema = new Schema({ type: String, enum: Genre, required: true + }, + actionIntensity: { + type: Number, + required: [ + function(this: { genre: Genre }) { + return this.genre === Genre.Action; + }, + 'Action intensity required for action genre' + ] } }); @@ -68,4 +77,4 @@ async function gh9857() { }; const schema = new Schema(schemaDefinition); -} \ No newline at end of file +}