Merge pull request #619 from ParsePlatform/nlutsenko.triggers.inflate
Improve beforeSave triggers for newly created objects.
This commit is contained in:
@@ -533,6 +533,48 @@ describe('miscellaneous', function() {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('pointer mutation properly saves object', done => {
|
||||||
|
let className = 'GameScore';
|
||||||
|
|
||||||
|
Parse.Cloud.beforeSave(className, (req, res) => {
|
||||||
|
let object = req.object;
|
||||||
|
expect(object instanceof Parse.Object).toBeTruthy();
|
||||||
|
|
||||||
|
let child = object.get('child');
|
||||||
|
expect(child instanceof Parse.Object).toBeTruthy();
|
||||||
|
child.set('a', 'b');
|
||||||
|
child.save().then(() => {
|
||||||
|
res.success();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
let obj = new Parse.Object(className);
|
||||||
|
obj.set('foo', 'bar');
|
||||||
|
|
||||||
|
let child = new Parse.Object('Child');
|
||||||
|
child.save().then(() => {
|
||||||
|
obj.set('child', child);
|
||||||
|
return obj.save();
|
||||||
|
}).then(() => {
|
||||||
|
let query = new Parse.Query(className);
|
||||||
|
query.include('child');
|
||||||
|
return query.get(obj.id).then(objAgain => {
|
||||||
|
expect(objAgain.get('foo')).toEqual('bar');
|
||||||
|
|
||||||
|
let childAgain = objAgain.get('child');
|
||||||
|
expect(childAgain instanceof Parse.Object).toBeTruthy();
|
||||||
|
expect(childAgain.get('a')).toEqual('b');
|
||||||
|
|
||||||
|
return Promise.resolve();
|
||||||
|
});
|
||||||
|
}).then(() => {
|
||||||
|
done();
|
||||||
|
}, error => {
|
||||||
|
fail(error);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('test afterSave get full object on create and update', function(done) {
|
it('test afterSave get full object on create and update', function(done) {
|
||||||
|
|||||||
@@ -111,6 +111,11 @@ RestWrite.prototype.validateSchema = function() {
|
|||||||
// Runs any beforeSave triggers against this operation.
|
// Runs any beforeSave triggers against this operation.
|
||||||
// Any change leads to our data being mutated.
|
// Any change leads to our data being mutated.
|
||||||
RestWrite.prototype.runBeforeTrigger = function() {
|
RestWrite.prototype.runBeforeTrigger = function() {
|
||||||
|
// Avoid doing any setup for triggers if there is no 'beforeSave' trigger for this class.
|
||||||
|
if (!triggers.triggerExists(this.className, triggers.Types.beforeSave)) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
// Cloud code gets a bit of extra data for its objects
|
// Cloud code gets a bit of extra data for its objects
|
||||||
var extraData = {className: this.className};
|
var extraData = {className: this.className};
|
||||||
if (this.query && this.query.objectId) {
|
if (this.query && this.query.objectId) {
|
||||||
@@ -118,17 +123,12 @@ RestWrite.prototype.runBeforeTrigger = function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let originalObject = null;
|
let originalObject = null;
|
||||||
let updatedObject = null;
|
let updatedObject = triggers.inflate(extraData, this.originalData);
|
||||||
if (this.query && this.query.objectId) {
|
if (this.query && this.query.objectId) {
|
||||||
// This is an update for existing object.
|
// This is an update for existing object.
|
||||||
originalObject = triggers.inflate(extraData, this.originalData);
|
originalObject = triggers.inflate(extraData, this.originalData);
|
||||||
updatedObject = triggers.inflate(extraData, this.originalData);
|
|
||||||
updatedObject.set(Parse._decode(undefined, this.data));
|
|
||||||
} else {
|
|
||||||
// This is create of an object, so no original object exists.
|
|
||||||
// TODO: (nlutsenko) Use the same flow as for creation, when _Session triggers support is removed.
|
|
||||||
updatedObject = triggers.inflate(extraData, this.data);
|
|
||||||
}
|
}
|
||||||
|
updatedObject.set(Parse._decode(undefined, this.data));
|
||||||
|
|
||||||
return Promise.resolve().then(() => {
|
return Promise.resolve().then(() => {
|
||||||
return triggers.maybeRunTrigger(
|
return triggers.maybeRunTrigger(
|
||||||
|
|||||||
19
src/index.js
19
src/index.js
@@ -211,24 +211,35 @@ function addParseCloud() {
|
|||||||
afterDelete: {}
|
afterDelete: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function validateClassNameForTriggers(className) {
|
||||||
|
const restrictedClassNames = [ '_Session' ];
|
||||||
|
if (restrictedClassNames.indexOf(className) != -1) {
|
||||||
|
throw `Triggers are not supported for ${className} class.`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Parse.Cloud.define = function(functionName, handler, validationHandler) {
|
Parse.Cloud.define = function(functionName, handler, validationHandler) {
|
||||||
Parse.Cloud.Functions[functionName] = handler;
|
Parse.Cloud.Functions[functionName] = handler;
|
||||||
Parse.Cloud.Validators[functionName] = validationHandler;
|
Parse.Cloud.Validators[functionName] = validationHandler;
|
||||||
};
|
};
|
||||||
Parse.Cloud.beforeSave = function(parseClass, handler) {
|
Parse.Cloud.beforeSave = function(parseClass, handler) {
|
||||||
var className = getClassName(parseClass);
|
let className = getClassName(parseClass);
|
||||||
|
validateClassNameForTriggers(className);
|
||||||
Parse.Cloud.Triggers.beforeSave[className] = handler;
|
Parse.Cloud.Triggers.beforeSave[className] = handler;
|
||||||
};
|
};
|
||||||
Parse.Cloud.beforeDelete = function(parseClass, handler) {
|
Parse.Cloud.beforeDelete = function(parseClass, handler) {
|
||||||
var className = getClassName(parseClass);
|
let className = getClassName(parseClass);
|
||||||
|
validateClassNameForTriggers(className);
|
||||||
Parse.Cloud.Triggers.beforeDelete[className] = handler;
|
Parse.Cloud.Triggers.beforeDelete[className] = handler;
|
||||||
};
|
};
|
||||||
Parse.Cloud.afterSave = function(parseClass, handler) {
|
Parse.Cloud.afterSave = function(parseClass, handler) {
|
||||||
var className = getClassName(parseClass);
|
let className = getClassName(parseClass);
|
||||||
|
validateClassNameForTriggers(className);
|
||||||
Parse.Cloud.Triggers.afterSave[className] = handler;
|
Parse.Cloud.Triggers.afterSave[className] = handler;
|
||||||
};
|
};
|
||||||
Parse.Cloud.afterDelete = function(parseClass, handler) {
|
Parse.Cloud.afterDelete = function(parseClass, handler) {
|
||||||
var className = getClassName(parseClass);
|
let className = getClassName(parseClass);
|
||||||
|
validateClassNameForTriggers(className);
|
||||||
Parse.Cloud.Triggers.afterDelete[className] = handler;
|
Parse.Cloud.Triggers.afterDelete[className] = handler;
|
||||||
};
|
};
|
||||||
Parse.Cloud.httpRequest = httpRequest;
|
Parse.Cloud.httpRequest = httpRequest;
|
||||||
|
|||||||
@@ -18,6 +18,10 @@ var getTrigger = function(className, triggerType) {
|
|||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function triggerExists(className: string, type: string): boolean {
|
||||||
|
return (getTrigger(className, type) != undefined);
|
||||||
|
}
|
||||||
|
|
||||||
var getRequestObject = function(triggerType, auth, parseObject, originalParseObject) {
|
var getRequestObject = function(triggerType, auth, parseObject, originalParseObject) {
|
||||||
var request = {
|
var request = {
|
||||||
triggerName: triggerType,
|
triggerName: triggerType,
|
||||||
@@ -52,7 +56,7 @@ var getResponseObject = function(request, resolve, reject) {
|
|||||||
success: function() {
|
success: function() {
|
||||||
var response = {};
|
var response = {};
|
||||||
if (request.triggerName === Types.beforeSave) {
|
if (request.triggerName === Types.beforeSave) {
|
||||||
response['object'] = request.object.toJSON();
|
response['object'] = request.object._getSaveJSON();
|
||||||
}
|
}
|
||||||
return resolve(response);
|
return resolve(response);
|
||||||
},
|
},
|
||||||
@@ -96,5 +100,6 @@ module.exports = {
|
|||||||
getRequestObject: getRequestObject,
|
getRequestObject: getRequestObject,
|
||||||
inflate: inflate,
|
inflate: inflate,
|
||||||
maybeRunTrigger: maybeRunTrigger,
|
maybeRunTrigger: maybeRunTrigger,
|
||||||
|
triggerExists: triggerExists,
|
||||||
Types: Types
|
Types: Types
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user