Skip to content

Commit 34f7741

Browse files
dblythyEmpiDev
authored andcommitted
feat: allow short circuit of beforeFind
1 parent 40bad26 commit 34f7741

File tree

3 files changed

+128
-22
lines changed

3 files changed

+128
-22
lines changed

spec/CloudCode.spec.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,61 @@ describe('Cloud Code', () => {
202202
}
203203
});
204204

205+
it('beforeFind can short circuit', async () => {
206+
Parse.Cloud.beforeFind('beforeFind', () => {
207+
return new Parse.Object('TestObject', { foo: 'bar' });
208+
});
209+
Parse.Cloud.afterFind('beforeFind', () => {
210+
throw 'afterFind should not run';
211+
});
212+
const obj = new Parse.Object('beforeFind');
213+
await obj.save();
214+
const newObj = await new Parse.Query('beforeFind').first();
215+
expect(newObj.className).toBe('TestObject');
216+
expect(newObj.toJSON()).toEqual({ foo: 'bar' });
217+
});
218+
219+
it('beforeFind can short circuit arrays', async () => {
220+
Parse.Cloud.beforeFind('beforeFind', () => {
221+
return [new Parse.Object('TestObject', { foo: 'bar' })];
222+
});
223+
Parse.Cloud.afterFind('beforeFind', () => {
224+
throw 'afterFind should not run';
225+
});
226+
const obj = new Parse.Object('beforeFind');
227+
await obj.save();
228+
const newObj = await new Parse.Query('beforeFind').first();
229+
expect(newObj.className).toBe('TestObject');
230+
expect(newObj.toJSON()).toEqual({ foo: 'bar' });
231+
});
232+
233+
it('beforeFind can short circuit get', async () => {
234+
Parse.Cloud.beforeFind('beforeFind', () => {
235+
return [new Parse.Object('TestObject', { foo: 'bar' })];
236+
});
237+
Parse.Cloud.afterFind('beforeFind', () => {
238+
throw 'afterFind should not run';
239+
});
240+
const obj = new Parse.Object('beforeFind');
241+
await obj.save();
242+
const newObj = await new Parse.Query('beforeFind').get(obj.id);
243+
expect(newObj.className).toBe('TestObject');
244+
expect(newObj.toJSON()).toEqual({ foo: 'bar' });
245+
});
246+
247+
it('beforeFind can short circuit empty array', async () => {
248+
Parse.Cloud.beforeFind('beforeFind', () => {
249+
return [];
250+
});
251+
Parse.Cloud.afterFind('beforeFind', () => {
252+
throw 'afterFind should not run';
253+
});
254+
const obj = new Parse.Object('beforeFind');
255+
await obj.save();
256+
const newObj = await new Parse.Query('beforeFind').first();
257+
expect(newObj).toBeUndefined();
258+
});
259+
205260
it('beforeSave rejection with custom error code', function (done) {
206261
Parse.Cloud.beforeSave('BeforeSaveFailWithErrorCode', function () {
207262
throw new Parse.Error(999, 'Nope');

src/rest.js

Lines changed: 63 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,33 +26,74 @@ function checkLiveQuery(className, config) {
2626

2727
// Returns a promise for an object with optional keys 'results' and 'count'.
2828
const find = async (config, auth, className, restWhere, restOptions, clientSDK, context) => {
29-
const query = await RestQuery({
30-
method: RestQuery.Method.find,
31-
config,
32-
auth,
33-
className,
34-
restWhere,
35-
restOptions,
36-
clientSDK,
37-
context,
38-
});
39-
return query.execute();
29+
enforceRoleSecurity('find', className, auth);
30+
return triggers
31+
.maybeRunQueryTrigger(
32+
triggers.Types.beforeFind,
33+
className,
34+
restWhere,
35+
restOptions,
36+
config,
37+
auth,
38+
context
39+
)
40+
.then(async result => {
41+
restWhere = result.restWhere || restWhere;
42+
restOptions = result.restOptions || restOptions;
43+
if (result?.objects) {
44+
return {
45+
results: result.objects.map(row => row._toFullJSON()),
46+
};
47+
}
48+
const query = await RestQuery({
49+
method: RestQuery.Method.find,
50+
config,
51+
auth,
52+
className,
53+
restWhere,
54+
restOptions,
55+
clientSDK,
56+
context,
57+
});
58+
return query.execute();
59+
});
4060
};
4161

4262
// get is just like find but only queries an objectId.
4363
const get = async (config, auth, className, objectId, restOptions, clientSDK, context) => {
4464
var restWhere = { objectId };
45-
const query = await RestQuery({
46-
method: RestQuery.Method.get,
47-
config,
48-
auth,
49-
className,
50-
restWhere,
51-
restOptions,
52-
clientSDK,
53-
context,
54-
});
55-
return query.execute();
65+
enforceRoleSecurity('get', className, auth);
66+
return triggers
67+
.maybeRunQueryTrigger(
68+
triggers.Types.beforeFind,
69+
className,
70+
restWhere,
71+
restOptions,
72+
config,
73+
auth,
74+
context,
75+
true
76+
)
77+
.then(async result => {
78+
restWhere = result.restWhere || restWhere;
79+
restOptions = result.restOptions || restOptions;
80+
if (result?.objects) {
81+
return {
82+
results: result.objects.map(row => row._toFullJSON()),
83+
};
84+
}
85+
const query = await RestQuery({
86+
method: RestQuery.Method.get,
87+
config,
88+
auth,
89+
className,
90+
restWhere,
91+
restOptions,
92+
clientSDK,
93+
context,
94+
});
95+
return query.execute();
96+
});
5697
};
5798

5899
// Returns a promise that doesn't resolve to any useful value.

src/triggers.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,9 +607,19 @@ export function maybeRunQueryTrigger(
607607
restOptions = restOptions || {};
608608
restOptions.subqueryReadPreference = requestObject.subqueryReadPreference;
609609
}
610+
let objects = undefined;
611+
if (result instanceof Parse.Object) {
612+
objects = [result];
613+
} else if (
614+
Array.isArray(result) &&
615+
(!result.length || result.some(obj => obj instanceof Parse.Object))
616+
) {
617+
objects = result;
618+
}
610619
return {
611620
restWhere,
612621
restOptions,
622+
objects,
613623
};
614624
},
615625
err => {

0 commit comments

Comments
 (0)