diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1d45774..9140dbf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - node: [14, 16, 18] + node: [16, 18, 20] os: [ubuntu-20.04] include: - os: ubuntu-20.04 diff --git a/CHANGELOG.md b/CHANGELOG.md index e5cf0c9..cd9c701 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +2.0.0 / 2024-03-07 +================== + * BREAKING CHANGE: call getters correctly on array elements for Mongoose 7.5.0, require Mongoose 7.5.0 #30 + 1.1.0 / 2023-06-01 ================== * feat: apply getters to schemas with discriminator #26 [remcorakers](https://github.com/remcorakers) diff --git a/README.md b/README.md index 8e4e627..3a8584d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # mongoose-lean-getters Apply getters on lean() documents: https://mongoosejs.com/docs/tutorials/lean.html +This package requires Mongoose `>= 7.1.0`. Do not use with Mongoose 7.0.x or 6.x. + ## Usage ```javascript @@ -21,4 +23,4 @@ await Model.create({ name: 'Captain Jean-Luc Picard' }); const doc = await Model.findOne().lean({ getters: true }); doc.name; // 'Picard' -``` \ No newline at end of file +``` diff --git a/index.js b/index.js index 5845a44..b521060 100644 --- a/index.js +++ b/index.js @@ -67,7 +67,7 @@ function applyGetters(schema, res, path) { } function getSchemaForDoc(schema, res) { - if (!schema.discriminatorMapping || !schema.discriminatorMapping.key) { + if (!schema.discriminatorMapping || !schema.discriminatorMapping.key || !schema.discriminators) { return schema; } @@ -85,15 +85,18 @@ function applyGettersToDoc(schema, doc, fields, prefix) { return; } - const schemaForDoc = getSchemaForDoc(schema, doc); - if (Array.isArray(doc)) { for (let i = 0; i < doc.length; ++i) { - applyGettersToDoc.call(this, schemaForDoc, doc[i], fields, prefix); + const currentDoc = doc[i]; + if (currentDoc == null) continue; + const schemaForDoc = getSchemaForDoc(schema, currentDoc); + applyGettersToDoc.call(this, schemaForDoc, currentDoc, fields, prefix); } return; } + const schemaForDoc = getSchemaForDoc(schema, doc); + schemaForDoc.eachPath((path, schematype) => { const pathWithPrefix = prefix ? prefix + '.' + path : path; if (this.selectedInclusively() && @@ -108,8 +111,20 @@ function applyGettersToDoc(schema, doc, fields, prefix) { !this.isPathSelectedInclusive(pathWithPrefix)) { return; } - if (mpath.has(path, doc)) { - mpath.set(path, schematype.applyGetters(mpath.get(path, doc), doc, true), doc); + + const pathExists = mpath.has(path, doc); + if (pathExists) { + if (schematype.$isMongooseArray && !schematype.$isMongooseDocumentArray) { + mpath.set( + path, + schematype.applyGetters(mpath.get(path, doc), doc, true).map(subdoc => { + return schematype.caster.applyGetters(subdoc, doc); + }), + doc + ); + } else { + mpath.set(path, schematype.applyGetters(mpath.get(path, doc), doc, true), doc); + } } }); } diff --git a/package.json b/package.json index 323e01b..3111db2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mongoose-lean-getters", - "version": "1.1.0", + "version": "2.0.0", "description": "Apply getters to the results of mongoose queries when using `.lean()`", "main": "index.js", "scripts": { @@ -34,10 +34,10 @@ "eslint": "5.16.0", "istanbul": "0.4.5", "mocha": "5.2.x", - "mongoose": ">= 7.1.0" + "mongoose": ">= 7.5.0" }, "peerDependencies": { - "mongoose": ">= 7.1.0" + "mongoose": ">= 7.5.0" }, "author": "Valeri Karpov ", "license": "Apache 2.0", diff --git a/test/examples.test.js b/test/examples.test.js index 8ce2e72..5154277 100644 --- a/test/examples.test.js +++ b/test/examples.test.js @@ -7,7 +7,7 @@ const mongooseLeanGetters = require('../'); describe('mongoose-lean-getters', function() { before(function() { - return mongoose.connect('mongodb://127.0.0.1:27017/test', { useNewUrlParser: true }); + return mongoose.connect('mongodb://127.0.0.1:27017/test'); }); after(() => mongoose.disconnect()); @@ -36,4 +36,4 @@ describe('mongoose-lean-getters', function() { assert.equal(doc.name, 'Picard'); }); -}); \ No newline at end of file +}); diff --git a/test/index.test.js b/test/index.test.js index 353c549..d163e46 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -7,7 +7,7 @@ const mongooseLeanGetters = require('../'); describe('mongoose-lean-getters', function() { before(function() { - return mongoose.connect('mongodb://127.0.0.1:27017/test', { useNewUrlParser: true }); + return mongoose.connect('mongodb://127.0.0.1:27017/test'); }); after(() => mongoose.disconnect()); @@ -249,6 +249,7 @@ describe('mongoose-lean-getters', function() { assert.equal(docs[0].url, 'https://www.test.com discriminator field'); }); + it('should call getters on schemas with discriminator using explicit value', async function() { const options = { discriminatorKey: 'kind' }; @@ -275,4 +276,58 @@ describe('mongoose-lean-getters', function() { assert.equal(docs[0].url, 'https://www.test.com discriminator field'); }); + + it('should work on schemas with discriminators in arrays', async function() { + const options = { discriminatorKey: 'kind' }; + + const eventSchema = new mongoose.Schema({ time: Date }, options); + const clickedLinkSchema = new mongoose.Schema({ + url: { type: String, get: v => v + ' discriminator field' } + }); + eventSchema.discriminator('ClickedLink', clickedLinkSchema); + + const eventListSchema = new mongoose.Schema({ + events: [eventSchema], + }); + eventListSchema.plugin(mongooseLeanGetters); + const EventList = mongoose.model('EventList', eventListSchema); + + await EventList.deleteMany({}); + await EventList.create({ + events: [{ + kind: 'ClickedLink', + url: 'https://www.test.com' + }], + }); + + const docs = await EventList.find().lean({ getters: true }); + + assert.equal(docs[0].events[0].url, 'https://www.test.com discriminator field'); + }); + + it('should call getters on arrays (gh-30)', async function() { + function upper(value) { + return value.toUpperCase(); + } + + const userSchema = new mongoose.Schema({ + name: { + type: String, + get: upper + }, + emails: [{ type: String, get: upper }] + }); + userSchema.plugin(mongooseLeanGetters); + const User = mongoose.model('User', userSchema); + + const user = new User({ + name: 'one', + emails: ['two', 'three'], + }); + await user.save(); + + const foundUser = await User.findById(user._id).lean({ getters: true }); + assert.strictEqual(user.name, 'ONE'); + assert.deepStrictEqual(foundUser.emails, ['TWO', 'THREE']); + }); });