Skip to content

Commit 4c6ba77

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents bf9e84b + cbe04f1 commit 4c6ba77

14 files changed

+1778
-5046
lines changed

CHANGELOG.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,29 @@
11
# Parse-SDK-JS
22

33
### master
4-
[Full Changelog](https://github.com/parse-community/Parse-SDK-JS/compare/2.13.0...master)
4+
[Full Changelog](https://github.com/parse-community/Parse-SDK-JS/compare/2.15.0...master)
5+
6+
## 2.15.0
7+
[Full Changelog](https://github.com/parse-community/Parse-SDK-JS/compare/2.14.0...2.15.0)
8+
9+
**Features**
10+
- New Parse.Error 159 DUPLICATE_REQUEST ([#1189](https://github.com/parse-community/Parse-SDK-JS/pull/1189))
11+
12+
**Fixes**
13+
- Live Query Subscription Error Event ([#1193](https://github.com/parse-community/Parse-SDK-JS/pull/1193))
14+
15+
## 2.14.0
16+
[Full Changelog](https://github.com/parse-community/Parse-SDK-JS/compare/2.13.0...2.14.0)
17+
18+
**New Features**
19+
- Passing context in destroy, saveAll, get, find hooks. ([#1159](https://github.com/parse-community/Parse-SDK-JS/pull/1159))
20+
- Support using aggregate on top of constructed query ([#1170](https://github.com/parse-community/Parse-SDK-JS/pull/1170))
21+
22+
**Improvements**
23+
- Performance improvement for Query.eachBatch ([#1179](https://github.com/parse-community/Parse-SDK-JS/pull/1179))
24+
25+
**Fixes**
26+
- Fix context for cascade saving ([#1186](https://github.com/parse-community/Parse-SDK-JS/pull/1186))
527

628
## 2.13.0
729
[Full Changelog](https://github.com/parse-community/Parse-SDK-JS/compare/2.12.0...2.13.0)

integration/test/ParseQueryAggregateTest.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,25 @@ describe('Parse Aggregate Query', () => {
9696
expect(results[0].tempPointer.value).toEqual(2);
9797
});
9898

99+
it('aggregate pipeline on top of a simple query', async done => {
100+
const pipeline = {
101+
group: { objectId: '$name' },
102+
};
103+
let results = await new Parse.Query(TestObject)
104+
.equalTo('name', 'foo')
105+
.aggregate(pipeline);
106+
107+
expect(results.length).toBe(1);
108+
109+
results = await new Parse.Query(TestObject)
110+
.equalTo('score', 20)
111+
.aggregate(pipeline);
112+
113+
expect(results.length).toBe(1);
114+
115+
done();
116+
});
117+
99118
it('distinct query', () => {
100119
const query = new Parse.Query(TestObject);
101120
return query.distinct('score').then((results) => {

package-lock.json

Lines changed: 1561 additions & 5033 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "parse",
3-
"version": "2.13.0",
3+
"version": "2.15.0",
44
"description": "The Parse JavaScript SDK",
55
"homepage": "https://parseplatform.org/",
66
"keywords": [
@@ -29,12 +29,12 @@
2929
"react-native": false
3030
},
3131
"dependencies": {
32-
"@babel/runtime": "7.10.2",
33-
"@babel/runtime-corejs3": "7.10.2",
32+
"@babel/runtime-corejs3": "7.10.4",
33+
"@babel/runtime": "7.10.4",
3434
"crypto-js": "4.0.0",
3535
"react-native-crypto-js": "1.0.0",
36-
"uuid": "3.3.3",
37-
"ws": "7.3.0",
36+
"uuid": "3.4.0",
37+
"ws": "7.3.1",
3838
"xmlhttprequest": "1.8.0"
3939
},
4040
"devDependencies": {
@@ -52,7 +52,7 @@
5252
"babel-plugin-minify-dead-code-elimination": "0.5.1",
5353
"babel-plugin-transform-inline-environment-variables": "0.4.3",
5454
"browserify": "16.5.1",
55-
"codecov": "3.7.0",
55+
"codecov": "3.7.1",
5656
"core-js": "3.6.5",
5757
"cross-env": "7.0.2",
5858
"eslint": "6.8.0",

src/Cloud.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ export function run(
5757
if (options.sessionToken) {
5858
requestOptions.sessionToken = options.sessionToken;
5959
}
60+
if (options.context && typeof options.context === 'object') {
61+
requestOptions.context = options.context;
62+
}
6063

6164
return CoreManager.getCloudController().run(name, data, requestOptions);
6265
}

src/LiveQueryClient.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ class LiveQueryClient extends EventEmitter {
381381
if (data.requestId) {
382382
if (subscription) {
383383
subscription.subscribePromise.resolve();
384-
subscription.emit(SUBSCRIPTION_EMMITER_TYPES.ERROR, data.error);
384+
setTimeout(() => subscription.emit(SUBSCRIPTION_EMMITER_TYPES.ERROR, data.error), 200);
385385
}
386386
} else {
387387
this.emit(CLIENT_EMMITER_TYPES.ERROR, data.error);

src/ParseError.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,15 @@ ParseError.FILE_DELETE_ERROR = 153;
353353
*/
354354
ParseError.REQUEST_LIMIT_EXCEEDED = 155;
355355

356+
/**
357+
* Error code indicating that the request was a duplicate and has been discarded due to
358+
* idempotency rules.
359+
* @property DUPLICATE_REQUEST
360+
* @static
361+
* @final
362+
*/
363+
ParseError.DUPLICATE_REQUEST = 159;
364+
356365
/**
357366
* Error code indicating an invalid event name.
358367
* @property INVALID_EVENT_NAME

src/ParseObject.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,7 @@ class ParseObject {
10841084
* behalf of a specific user.
10851085
* <li>include: The name(s) of the key(s) to include. Can be a string, an array of strings,
10861086
* or an array of array of strings.
1087+
* <li>context: A dictionary that is accessible in Cloud Code `beforeFind` trigger.
10871088
* </ul>
10881089
* @return {Promise} A promise that is fulfilled when the fetch
10891090
* completes.
@@ -1097,6 +1098,9 @@ class ParseObject {
10971098
if (options.hasOwnProperty('sessionToken')) {
10981099
fetchOptions.sessionToken = options.sessionToken;
10991100
}
1101+
if (options.hasOwnProperty('context') && typeof options.context === 'object') {
1102+
fetchOptions.context = options.context;
1103+
}
11001104
if (options.hasOwnProperty('include')) {
11011105
fetchOptions.include = [];
11021106
if (Array.isArray(options.include)) {
@@ -1273,6 +1277,7 @@ class ParseObject {
12731277
* be used for this request.
12741278
* <li>sessionToken: A valid session token, used for making a request on
12751279
* behalf of a specific user.
1280+
* <li>context: A dictionary that is accessible in Cloud Code `beforeDelete` and `afterDelete` triggers.
12761281
* </ul>
12771282
* @return {Promise} A promise that is fulfilled when the destroy
12781283
* completes.
@@ -1286,6 +1291,9 @@ class ParseObject {
12861291
if (options.hasOwnProperty('sessionToken')) {
12871292
destroyOptions.sessionToken = options.sessionToken;
12881293
}
1294+
if (options.hasOwnProperty('context') && typeof options.context === 'object') {
1295+
destroyOptions.context = options.context;
1296+
}
12891297
if (!this.id) {
12901298
return Promise.resolve();
12911299
}
@@ -1631,6 +1639,7 @@ class ParseObject {
16311639
* <li>sessionToken: A valid session token, used for making a request on
16321640
* behalf of a specific user.
16331641
* <li>batchSize: Number of objects to process per request
1642+
* <li>context: A dictionary that is accessible in Cloud Code `beforeDelete` and `afterDelete` triggers.
16341643
* </ul>
16351644
* @return {Promise} A promise that is fulfilled when the destroyAll
16361645
* completes.
@@ -1646,6 +1655,9 @@ class ParseObject {
16461655
if (options.hasOwnProperty('batchSize') && typeof options.batchSize === 'number') {
16471656
destroyOptions.batchSize = options.batchSize;
16481657
}
1658+
if (options.hasOwnProperty('context') && typeof options.context === 'object') {
1659+
destroyOptions.context = options.context;
1660+
}
16491661
return CoreManager.getObjectController().destroy(
16501662
list,
16511663
destroyOptions
@@ -1674,6 +1686,7 @@ class ParseObject {
16741686
* <li>sessionToken: A valid session token, used for making a request on
16751687
* behalf of a specific user.
16761688
* <li>batchSize: Number of objects to process per request
1689+
* <li>context: A dictionary that is accessible in Cloud Code `beforeSave` and `afterSave` triggers.
16771690
* </ul>
16781691
*/
16791692
static saveAll(list: Array<ParseObject>, options: RequestOptions = {}) {
@@ -1687,6 +1700,9 @@ class ParseObject {
16871700
if (options.hasOwnProperty('batchSize') && typeof options.batchSize === 'number') {
16881701
saveOptions.batchSize = options.batchSize;
16891702
}
1703+
if (options.hasOwnProperty('context') && typeof options.context === 'object') {
1704+
saveOptions.context = options.context;
1705+
}
16901706
return CoreManager.getObjectController().save(
16911707
list,
16921708
saveOptions

src/ParseQuery.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,7 @@ class ParseQuery {
564564
* be used for this request.
565565
* <li>sessionToken: A valid session token, used for making a request on
566566
* behalf of a specific user.
567+
* <li>context: A dictionary that is accessible in Cloud Code `beforeFind` trigger.
567568
* </ul>
568569
*
569570
* @return {Promise} A promise that is resolved with the result when
@@ -579,6 +580,9 @@ class ParseQuery {
579580
if (options && options.hasOwnProperty('sessionToken')) {
580581
firstOptions.sessionToken = options.sessionToken;
581582
}
583+
if (options && options.hasOwnProperty('context') && typeof options.context === 'object') {
584+
firstOptions.context = options.context;
585+
}
582586

583587
return this.first(firstOptions).then((response) => {
584588
if (response) {
@@ -604,6 +608,7 @@ class ParseQuery {
604608
* be used for this request.
605609
* <li>sessionToken: A valid session token, used for making a request on
606610
* behalf of a specific user.
611+
* <li>context: A dictionary that is accessible in Cloud Code `beforeFind` trigger.
607612
* </ul>
608613
*
609614
* @return {Promise} A promise that is resolved with the results when
@@ -619,6 +624,9 @@ class ParseQuery {
619624
if (options.hasOwnProperty('sessionToken')) {
620625
findOptions.sessionToken = options.sessionToken;
621626
}
627+
if (options.hasOwnProperty('context') && typeof options.context === 'object') {
628+
findOptions.context = options.context;
629+
}
622630
this._setRequestTask(findOptions);
623631

624632
const controller = CoreManager.getQueryController();
@@ -773,6 +781,11 @@ class ParseQuery {
773781
throw new Error('Invalid pipeline must be Array or Object');
774782
}
775783

784+
if (Object.keys(this._where || {}).length) {
785+
if(!Array.isArray(pipeline)) pipeline = [pipeline];
786+
pipeline.unshift({ match: this._where });
787+
}
788+
776789
const params = {
777790
pipeline,
778791
hint: this._hint,
@@ -799,6 +812,7 @@ class ParseQuery {
799812
* be used for this request.
800813
* <li>sessionToken: A valid session token, used for making a request on
801814
* behalf of a specific user.
815+
* <li>context: A dictionary that is accessible in Cloud Code `beforeFind` trigger.
802816
* </ul>
803817
*
804818
* @return {Promise} A promise that is resolved with the object when
@@ -814,6 +828,9 @@ class ParseQuery {
814828
if (options.hasOwnProperty('sessionToken')) {
815829
findOptions.sessionToken = options.sessionToken;
816830
}
831+
if (options.hasOwnProperty('context') && typeof options.context === 'object') {
832+
findOptions.context = options.context;
833+
}
817834
this._setRequestTask(findOptions);
818835

819836
const controller = CoreManager.getQueryController();
@@ -871,6 +888,7 @@ class ParseQuery {
871888
* be used for this request.
872889
* <li>sessionToken: A valid session token, used for making a request on
873890
* behalf of a specific user.
891+
* <li>context: A dictionary that is accessible in Cloud Code `beforeFind` trigger.
874892
* </ul>
875893
* @return {Promise} A promise that will be fulfilled once the
876894
* iteration has completed.
@@ -921,6 +939,9 @@ class ParseQuery {
921939
if (options.hasOwnProperty('sessionToken')) {
922940
findOptions.sessionToken = options.sessionToken;
923941
}
942+
if (options.hasOwnProperty('context') && typeof options.context === 'object') {
943+
findOptions.context = options.context;
944+
}
924945

925946
let finished = false;
926947
let previousResults = [];

src/RESTController.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,6 @@ const RESTController = {
227227
const context = options.context;
228228
if (context !== undefined) {
229229
payload._context = context;
230-
delete options.context;
231230
}
232231

233232
if (method !== 'POST') {

src/__tests__/Cloud-test.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,4 +205,21 @@ describe('CloudController', () => {
205205
expect(CoreManager.getRESTController().request.mock.calls[0])
206206
.toEqual(['GET', 'cloud_code/jobs/data', null, { useMasterKey: true }]);
207207
});
208+
209+
it('accepts context on cloud function call', async () => {
210+
const request = jest.fn();
211+
request.mockReturnValue(Promise.resolve(undefined));
212+
213+
const ajax = jest.fn();
214+
CoreManager.setRESTController({ request: request, ajax: ajax });
215+
216+
// Spy on REST controller
217+
const controller = CoreManager.getRESTController();
218+
jest.spyOn(controller, 'request');
219+
// Save object
220+
const context = {a: "a"};
221+
await Cloud.run('myfunction', {}, { context: context });
222+
// Validate
223+
expect(controller.request.mock.calls[0][3].context).toEqual(context);
224+
});
208225
});

src/__tests__/LiveQueryClient-test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ describe('LiveQueryClient', () => {
244244

245245
liveQueryClient._handleWebSocketMessage(event);
246246

247+
jest.runOnlyPendingTimers();
247248
expect(isChecked).toBe(true);
248249
});
249250

0 commit comments

Comments
 (0)