diff --git a/src/ParseObject.js b/src/ParseObject.js index a10999ff3..5f78cb191 100644 --- a/src/ParseObject.js +++ b/src/ParseObject.js @@ -56,7 +56,8 @@ type SaveParams = { }; type SaveOptions = FullOptions & { - cascadeSave?: boolean + cascadeSave?: boolean; + context?: AttributeMap; } // Mapping of class names to constructors, so we can populate objects from the @@ -1179,6 +1180,7 @@ class ParseObject { *
  • sessionToken: A valid session token, used for making a request on * behalf of a specific user. *
  • cascadeSave: If `false`, nested objects will not be saved (default is `true`). + *
  • context: A dictionary that is accessible in Cloud Code `beforeSave` and `afterSave` triggers. * *
  • * @@ -1192,6 +1194,7 @@ class ParseObject { *
  • sessionToken: A valid session token, used for making a request on * behalf of a specific user. *
  • cascadeSave: If `false`, nested objects will not be saved (default is `true`). + *
  • context: A dictionary that is accessible in Cloud Code `beforeSave` and `afterSave` triggers. * * * @return {Promise} A promise that is fulfilled when the save @@ -1251,6 +1254,9 @@ class ParseObject { if (options.hasOwnProperty('installationId') && typeof options.installationId === 'string') { saveOptions.installationId = options.installationId; } + if (options.hasOwnProperty('context') && typeof options.context === 'object') { + saveOptions.context = options.context; + } const controller = CoreManager.getObjectController(); const unsaved = options.cascadeSave !== false ? unsavedChildren(this) : null; return controller.save(unsaved, saveOptions).then(() => { diff --git a/src/RESTController.js b/src/RESTController.js index 1b3006a6d..82e3d3195 100644 --- a/src/RESTController.js +++ b/src/RESTController.js @@ -21,6 +21,7 @@ export type RequestOptions = { batchSize?: number; include?: any; progress?: any; + context?: any; }; export type FullOptions = { @@ -222,6 +223,13 @@ const RESTController = { } } + // Add context + const context = options.context; + if (context !== undefined) { + payload._context = context; + delete options.context; + } + if (method !== 'POST') { payload._method = method; method = 'POST'; diff --git a/src/__tests__/ParseObject-test.js b/src/__tests__/ParseObject-test.js index cc917da61..e055a9d0e 100644 --- a/src/__tests__/ParseObject-test.js +++ b/src/__tests__/ParseObject-test.js @@ -1219,6 +1219,26 @@ describe('ParseObject', () => { }); }); + it('accepts context on save', async () => { + // Mock XHR + CoreManager.getRESTController()._setXHR( + mockXHR([{ + status: 200, + response: { objectId: 'newattributes' } + }]) + ); + // Spy on REST controller + const controller = CoreManager.getRESTController(); + jest.spyOn(controller, 'ajax'); + // Save object + const context = {a: "a"}; + const obj = new ParseObject('Item'); + await obj.save(null, {context}); + // Validate + const jsonBody = JSON.parse(controller.ajax.mock.calls[0][2]); + expect(jsonBody._context).toEqual(context); + }); + it('interpolates delete operations', (done) => { CoreManager.getRESTController()._setXHR( mockXHR([{