Skip to content

Commit

Permalink
fix: allow array getters to return non-arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryan Wheale committed Jul 11, 2024
1 parent 32e828a commit 5dfba6b
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 3 deletions.
10 changes: 7 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,15 @@ function applyGettersToDoc(schema, doc, fields, prefix) {
const pathExists = mpath.has(path, doc);
if (pathExists) {
if (schematype.$isMongooseArray && !schematype.$isMongooseDocumentArray) {
// A getter may return a non-array
const got = schematype.applyGetters(mpath.get(path, doc), doc, true);
const val = Array.isArray(got) ? got.map(subdoc => {
return schematype.caster.applyGetters(subdoc, doc);
}) : schematype.caster.applyGetters(got, doc);

mpath.set(
path,
schematype.applyGetters(mpath.get(path, doc), doc, true).map(subdoc => {
return schematype.caster.applyGetters(subdoc, doc);
}),
val,
doc
);
} else {
Expand Down
31 changes: 31 additions & 0 deletions test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -384,4 +384,35 @@ describe('mongoose-lean-getters', function() {
assert.equal(typeof doc.field, 'string');
assert.strictEqual(doc.field, '1337');
});

it('should should allow getters to transform return type', async function() {
const userSchema = new mongoose.Schema({
emails: {
type: [String],
// returns undefined, string, or array
get: (val) => !val || !val.length ? undefined : (val.length === 1 ? val[0] : val),
set: (val) => typeof val === 'string' ? [val] : val,
}
});
userSchema.plugin(mongooseLeanGetters);
const User = mongoose.model('transform-arrays', userSchema);

const variants = [
{ sourceVal: 'foo', expectedVal: 'foo' },
{ sourceVal: ['foo'], expectedVal: 'foo' },
{ sourceVal: ['foo', 'bar'], expectedVal: ['foo', 'bar'] },
{ sourceVal: undefined, expectedVal: undefined },
];

await Promise.all(
variants.map(async({ sourceVal, expectedVal }) => {
const user = new User({ emails: sourceVal });
await user.save();

const foundUser = await User.findById(user._id).lean({ getters: true });
assert.deepStrictEqual(user.emails, expectedVal, `user did not have expected value { sourceVal: ${sourceVal}, expectedVal: ${expectedVal} }`);
assert.deepStrictEqual(foundUser.emails, expectedVal, `foundUser did not have expected value { sourceVal: ${sourceVal}, expectedVal: ${expectedVal}`);
})
);
});
});

0 comments on commit 5dfba6b

Please sign in to comment.