Skip to content

Commit 9816285

Browse files
RaschidJFRdplewis
authored andcommitted
Added rest option: excludeKeys (#5737)
* Added restOption: excludeKeys * improve tests
1 parent 378e70a commit 9816285

File tree

3 files changed

+149
-0
lines changed

3 files changed

+149
-0
lines changed

spec/ParseQuery.spec.js

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3348,6 +3348,122 @@ describe('Parse.Query testing', () => {
33483348
}
33493349
);
33503350
});
3351+
it('exclude keys', async () => {
3352+
const obj = new TestObject({ foo: 'baz', hello: 'world' });
3353+
await obj.save();
3354+
3355+
const response = await request({
3356+
url: Parse.serverURL + '/classes/TestObject',
3357+
qs: {
3358+
excludeKeys: 'foo',
3359+
where: JSON.stringify({ objectId: obj.id }),
3360+
},
3361+
headers: masterKeyHeaders,
3362+
});
3363+
expect(response.data.results[0].foo).toBeUndefined();
3364+
expect(response.data.results[0].hello).toBe('world');
3365+
});
3366+
3367+
it('exclude keys with select same key', async () => {
3368+
const obj = new TestObject({ foo: 'baz', hello: 'world' });
3369+
await obj.save();
3370+
3371+
const response = await request({
3372+
url: Parse.serverURL + '/classes/TestObject',
3373+
qs: {
3374+
keys: 'foo',
3375+
excludeKeys: 'foo',
3376+
where: JSON.stringify({ objectId: obj.id }),
3377+
},
3378+
headers: masterKeyHeaders,
3379+
});
3380+
expect(response.data.results[0].foo).toBeUndefined();
3381+
expect(response.data.results[0].hello).toBeUndefined();
3382+
});
3383+
3384+
it('exclude keys with select different key', async () => {
3385+
const obj = new TestObject({ foo: 'baz', hello: 'world' });
3386+
await obj.save();
3387+
3388+
const response = await request({
3389+
url: Parse.serverURL + '/classes/TestObject',
3390+
qs: {
3391+
keys: 'foo,hello',
3392+
excludeKeys: 'foo',
3393+
where: JSON.stringify({ objectId: obj.id }),
3394+
},
3395+
headers: masterKeyHeaders,
3396+
});
3397+
expect(response.data.results[0].foo).toBeUndefined();
3398+
expect(response.data.results[0].hello).toBe('world');
3399+
});
3400+
3401+
it('exclude keys with include same key', async () => {
3402+
const pointer = new TestObject();
3403+
await pointer.save();
3404+
const obj = new TestObject({ child: pointer, hello: 'world' });
3405+
await obj.save();
3406+
3407+
const response = await request({
3408+
url: Parse.serverURL + '/classes/TestObject',
3409+
qs: {
3410+
include: 'child',
3411+
excludeKeys: 'child',
3412+
where: JSON.stringify({ objectId: obj.id }),
3413+
},
3414+
headers: masterKeyHeaders,
3415+
});
3416+
expect(response.data.results[0].child).toBeUndefined();
3417+
expect(response.data.results[0].hello).toBe('world');
3418+
});
3419+
3420+
it('exclude keys with include different key', async () => {
3421+
const pointer = new TestObject();
3422+
await pointer.save();
3423+
const obj = new TestObject({
3424+
child1: pointer,
3425+
child2: pointer,
3426+
hello: 'world',
3427+
});
3428+
await obj.save();
3429+
3430+
const response = await request({
3431+
url: Parse.serverURL + '/classes/TestObject',
3432+
qs: {
3433+
include: 'child1,child2',
3434+
excludeKeys: 'child1',
3435+
where: JSON.stringify({ objectId: obj.id }),
3436+
},
3437+
headers: masterKeyHeaders,
3438+
});
3439+
expect(response.data.results[0].child1).toBeUndefined();
3440+
expect(response.data.results[0].child2.objectId).toEqual(pointer.id);
3441+
expect(response.data.results[0].hello).toBe('world');
3442+
});
3443+
3444+
it('exclude keys with includeAll', async () => {
3445+
const pointer = new TestObject();
3446+
await pointer.save();
3447+
const obj = new TestObject({
3448+
child1: pointer,
3449+
child2: pointer,
3450+
hello: 'world',
3451+
});
3452+
await obj.save();
3453+
3454+
const response = await request({
3455+
url: Parse.serverURL + '/classes/TestObject',
3456+
qs: {
3457+
includeAll: true,
3458+
excludeKeys: 'child1',
3459+
where: JSON.stringify({ objectId: obj.id }),
3460+
},
3461+
headers: masterKeyHeaders,
3462+
});
3463+
expect(response.data.results[0].child).toBeUndefined();
3464+
expect(response.data.results[0].child2.objectId).toEqual(pointer.id);
3465+
expect(response.data.results[0].hello).toBe('world');
3466+
});
33513467

33523468
it('select keys with each query', function(done) {
33533469
const obj = new TestObject({ foo: 'baz', bar: 1 });

src/RestQuery.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const AlwaysSelectedKeys = ['objectId', 'createdAt', 'updatedAt', 'ACL'];
1313
// count
1414
// include
1515
// keys
16+
// excludeKeys
1617
// redirectClassNameForKey
1718
// readPreference
1819
// includeReadPreference
@@ -102,6 +103,13 @@ function RestQuery(
102103
this.keys = Array.from(new Set(keys));
103104
break;
104105
}
106+
case 'excludeKeys': {
107+
const exclude = restOptions.excludeKeys
108+
.split(',')
109+
.filter(k => AlwaysSelectedKeys.indexOf(k) < 0);
110+
this.excludeKeys = Array.from(new Set(exclude));
111+
break;
112+
}
105113
case 'count':
106114
this.doCount = true;
107115
break;
@@ -184,6 +192,9 @@ RestQuery.prototype.execute = function(executeOptions) {
184192
.then(() => {
185193
return this.handleIncludeAll();
186194
})
195+
.then(() => {
196+
return this.handleExcludeKeys();
197+
})
187198
.then(() => {
188199
return this.runFind(executeOptions);
189200
})
@@ -705,6 +716,24 @@ RestQuery.prototype.handleIncludeAll = function() {
705716
});
706717
};
707718

719+
// Updates property `this.keys` to contain all keys but the ones unselected.
720+
RestQuery.prototype.handleExcludeKeys = function() {
721+
if (!this.excludeKeys) {
722+
return;
723+
}
724+
if (this.keys) {
725+
this.keys = this.keys.filter(k => !this.excludeKeys.includes(k));
726+
return;
727+
}
728+
return this.config.database
729+
.loadSchema()
730+
.then(schemaController => schemaController.getOneSchema(this.className))
731+
.then(schema => {
732+
const fields = Object.keys(schema.fields);
733+
this.keys = fields.filter(k => !this.excludeKeys.includes(k));
734+
});
735+
};
736+
708737
// Augments this.response with data at the paths provided in this.include.
709738
RestQuery.prototype.handleInclude = function() {
710739
if (this.include.length == 0) {

src/Routers/ClassesRouter.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ export class ClassesRouter extends PromiseRouter {
165165
'order',
166166
'count',
167167
'keys',
168+
'excludeKeys',
168169
'include',
169170
'includeAll',
170171
'redirectClassNameForKey',
@@ -200,6 +201,9 @@ export class ClassesRouter extends PromiseRouter {
200201
if (typeof body.keys == 'string') {
201202
options.keys = body.keys;
202203
}
204+
if (typeof body.excludeKeys == 'string') {
205+
options.excludeKeys = body.excludeKeys;
206+
}
203207
if (body.include) {
204208
options.include = String(body.include);
205209
}

0 commit comments

Comments
 (0)