Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 9 additions & 19 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,15 @@ const attachVirtualsFnMap = new WeakMap();

module.exports = function mongooseLeanVirtuals(schema, options) {
const fn = attachVirtualsMiddleware(schema, options);
schema.pre('find', function() {
if (typeof this.map === 'function') {
this.map((res) => {
fn.call(this, res);
return res;
});
} else {
this.options.transform = (res) => {
fn.call(this, res);
return res;
};
}
schema.pre(['find', 'findOne', 'findOneAndUpdate', 'findOneAndDelete', 'findOneAndReplace'], function mongooseLeanVirtualsMiddleware() {
const _this = this;
// Unshift makes this transform run before any other transforms (as well as before middleware because middleware runs after transforms).
// This is to make sure user-specified transforms don't give this transform an unexpected data structure - see gh-75.
Comment thread
vkarpov15 marked this conversation as resolved.
Outdated
this._transforms.unshift(function applyLeanVirtuals(res) {
fn.call(_this, res);
return res;
});
});

schema.post('find', fn);
schema.post('findOne', fn);
schema.post('findOneAndUpdate', fn);
schema.post('findOneAndRemove', fn);
schema.post('findOneAndDelete', fn);
};

module.exports.parent = function(obj) {
Expand All @@ -43,7 +33,7 @@ module.exports.parent = function(obj) {
};

function attachVirtualsMiddleware(schema, options = {}) {
return function(res) {
return function attachVirtualsToQueryResult(res) {
let virtuals = this._mongooseOptions.lean && this._mongooseOptions.lean.virtuals != null ? this._mongooseOptions.lean.virtuals : options.enabledByDefault;
if (virtuals) {
if (Array.isArray(virtuals)) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"typescript": "5.x"
},
"peerDependencies": {
"mongoose": ">=5.11.10"
"mongoose": ">=8.0.0"
},
"author": "Valeri Karpov <val@karpov.io>",
"license": "Apache 2.0",
Expand Down
49 changes: 41 additions & 8 deletions test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ const supportedOps = {
leanOptions = leanOptions || defaultLeanOptions;
return model.findOneAndDelete({ _id: docId }).lean(leanOptions).exec();
},
'findOneAndReplace': function(model, docId, leanOptions) {
leanOptions = leanOptions || defaultLeanOptions;
return model.findOneAndReplace({ _id: docId }, { ...baseObj }).lean(leanOptions).exec();
}
};
const supportedOpsKeys = Object.keys(supportedOps);

Expand Down Expand Up @@ -776,35 +780,64 @@ describe('Discriminators work', () => {
childSchema.virtual('uri').get(function() {
// This `uri` virtual is in a subdocument, so in order to get the
// parent's `uri` you need to use this plugin's `parent()` function.

const parent = this instanceof mongoose.Document
? this.parent()
: mongooseLeanVirtuals.parent(this)
;
return `${parent.uri}/child/gh-64-child`;
});

const parentSchema = new mongoose.Schema({
child: childSchema
});
parentSchema.virtual('uri').get(function() {
return `/parent/gh-64-parent`;
});

parentSchema.plugin(mongooseLeanVirtuals);

const Parent = mongoose.model('gh64', parentSchema);

const doc = { child: {} };

await Parent.create(doc);

let result = await Parent
.findOne()
.lean({ virtuals: true });
assert.equal(
result.child.uri,
'/parent/gh-64-parent/child/gh-64-child'
);
);
});

it('with transform (gh-75)', async function() {
const schema = new mongoose.Schema({ name: String });
schema.virtual('lower').get(function() {
return this.name.toLowerCase();
});

schema.plugin(mongooseLeanVirtuals);
const Model = mongoose.model('gh75', schema);

await Model.create([
{ name: 'JOHN' },
{ name: 'JANE' }
]);

const docs = await Model.find().lean({ virtuals: true }).transform((docs) => {
const map = {};
docs.forEach(doc => {
map[doc._id.toString()] = doc;
});
return map;
});

assert.equal(Object.keys(docs).length, 2);
for (const id in docs) {
const doc = docs[id];
Comment thread
vkarpov15 marked this conversation as resolved.
Outdated
assert.equal(doc.name.toLowerCase(), doc.lower);
}
});
});
Loading