Skip to content
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ ___
- Add building Docker image as CI check (Manuel Trezza) [#7332](https://github.com/parse-community/parse-server/pull/7332)
- Add NPM package-lock version check to CI (Manuel Trezza) [#7333](https://github.com/parse-community/parse-server/pull/7333)
- Fix incorrect LiveQuery events triggered for multiple subscriptions on the same class with different events [#7341](https://github.com/parse-community/parse-server/pull/7341)
- Updates on deeply nested documents keys are now correctly passed to afterSave triggers (Kartal Kaan Bozdogan - Ocell) [#7385](https://github.com/parse-community/parse-server/pull/7385)
___
## 4.5.0
[Full Changelog](https://github.com/parse-community/parse-server/compare/4.4.0...4.5.0)
Expand Down
33 changes: 20 additions & 13 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"mime": "2.5.2",
"mongodb": "3.6.6",
"mustache": "4.2.0",
"parse": "3.2.0",
"parse": "github:Ocell-io/Parse-SDK-JS#1ed03b3dca8af9c648606f95a6cb473b36b33a04",
"pg-monitor": "1.4.1",
"pg-promise": "10.10.1",
"pluralize": "8.0.0",
Expand Down
51 changes: 51 additions & 0 deletions spec/ParseAPI.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,57 @@ describe('miscellaneous', function () {
);
});

it('test afterSave with deeply nested keys (#7384)', async () => {
let triggerTime = 0;
Parse.Cloud.afterSave('GameScore', function (req) {
const object = req.object;
expect(object instanceof Parse.Object).toBeTruthy();
triggerTime++;
if (triggerTime == 1) {
// Create
expect(object.get('a')).toEqual({ b: 0, c: { d: 1 } });
expect(object.get('e')).toEqual(2);
} else if (triggerTime == 2) {
// Update, increment
expect(object.get('a')).toEqual({ b: 10, c: { d: 12 } });
expect(object.get('e')).toEqual(14);
} else if (triggerTime == 3) {
// Update, set
expect(object.get('a')).toEqual({ b: 100, c: { d: 200 } });
expect(object.get('e')).toEqual(300);
} else if (triggerTime == 4) {
// Update, unset on a.c.d
expect(object.get('a')).toEqual({ b: 100, c: {} });
expect(object.get('e')).toEqual(300);
} else if (triggerTime == 5) {
// Update, unset on a.b
expect(object.get('a')).toEqual({ c: {} });
expect(object.get('e')).toEqual(300);
} else {
throw new Error();
}
});

const obj = new Parse.Object('GameScore');
obj.set('a', { b: 0, c: { d: 1 } });
obj.set('e', 2);
await obj.save();
obj.increment('a.b', 10);
obj.increment('a.c.d', 11);
obj.increment('e', 12);
await obj.save();
obj.set('a.b', 100);
obj.set('a.c.d', 200);
obj.set('e', 300);
await obj.save();
obj.unset('a.c.d');
await obj.save();
obj.unset('a.b');
await obj.save();
// Make sure the checking has been triggered
expect(triggerTime).toBe(5);
});

it('test afterSave get original object on update', function (done) {
let triggerTime = 0;
// Register a mock beforeSave hook
Expand Down
2 changes: 1 addition & 1 deletion spec/ParseUser.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,7 @@ describe('Parse.User testing', () => {

user.set('username', 'test');
await user.save();
equal(Object.keys(user.attributes).length, 6);
equal(Object.keys(user.attributes).length, 5);
ok(user.attributes['username']);
ok(user.attributes['email']);
await user.destroy();
Expand Down
14 changes: 1 addition & 13 deletions src/RestWrite.js
Original file line number Diff line number Diff line change
Expand Up @@ -1589,19 +1589,7 @@ RestWrite.prototype.buildUpdatedObject = function (extraData) {
const updatedObject = triggers.inflate(extraData, this.originalData);
Object.keys(this.data).reduce(function (data, key) {
if (key.indexOf('.') > 0) {
if (typeof data[key].__op === 'string') {
updatedObject.set(key, data[key]);
} else {
// subdocument key with dot notation { 'x.y': v } => { 'x': { 'y' : v } })
const splittedKey = key.split('.');
const parentProp = splittedKey[0];
let parentVal = updatedObject.get(parentProp);
if (typeof parentVal !== 'object') {
parentVal = {};
}
parentVal[splittedKey[1]] = data[key];
updatedObject.set(parentProp, parentVal);
}
updatedObject.set(key, data[key]);
delete data[key];
}
return data;
Expand Down