Skip to content

Commit

Permalink
fix(array): apply fix for #12294 to nested paths
Browse files Browse the repository at this point in the history
  • Loading branch information
vkarpov15 committed Sep 11, 2022
1 parent b97d410 commit 316c54b
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
39 changes: 38 additions & 1 deletion lib/types/array/methods/index.js
Expand Up @@ -5,6 +5,7 @@ const ArraySubdocument = require('../../ArraySubdocument');
const MongooseError = require('../../../error/mongooseError');
const cleanModifiedSubpaths = require('../../../helpers/document/cleanModifiedSubpaths');
const internalToObjectOptions = require('../../../options').internalToObjectOptions;
const mpath = require('mpath');
const utils = require('../../../utils');
const isBsonType = require('../../../helpers/isBsonType');

Expand Down Expand Up @@ -349,7 +350,9 @@ const methods = {
}

Object.keys(v.$__.activePaths.getStatePaths('default')).forEach(path => {
delete ret[path];
mpath.unset(path, ret);

_minimizePath(ret, path);
});

return ret;
Expand Down Expand Up @@ -937,6 +940,40 @@ function _isAllSubdocs(docs, ref) {
return true;
}

/*!
* Minimize _just_ empty objects along the path chain specified
* by `parts`, ignoring all other paths. Useful in cases where
* you want to minimize after unsetting a path.
*
* #### Example:
*
* const obj = { foo: { bar: { baz: {} } }, a: {} };
* _minimizePath(obj, 'foo.bar.baz');
* obj; // { a: {} }
*/

function _minimizePath(obj, parts, i) {
if (typeof parts === 'string') {
if (parts.indexOf('.') === -1) {
return;
}

parts = mpath.stringToParts(parts);
}
i = i || 0;
if (i >= parts.length) {
return;
}
if (obj == null || typeof obj !== 'object') {
return;
}

_minimizePath(obj[parts[0]], parts, i + 1);
if (obj[parts[0]] != null && typeof obj[parts[0]] === 'object' && Object.keys(obj[parts[0]]).length === 0) {
delete obj[parts[0]];
}
}

/*!
* ignore
*/
Expand Down
3 changes: 3 additions & 0 deletions test/types.array.test.js
Expand Up @@ -829,6 +829,9 @@ describe('types array', function() {
colors: [{
_id: false,
hex: { type: String, default: '#ffffff' },
properties: {
hue: { type: Number, default: 0 }
},
name: String
}]
});
Expand Down

0 comments on commit 316c54b

Please sign in to comment.