Fix select exclude queries (#7242)

* fix keys and excludeKeys to work with JSON array strings

* make excludeKeys test more robust

* add changelog

* add select([]) functionality to fix)

* update changelog

* update keys

* add exclude test

* add select REST test and exclude JS SDK test

* add more tests

* add additional exclude test

* improved select test for testing JSON string array in REST

* improved exclude test for testing JSON string array in REST

* check for parse keys

* make include look like keys and excludeKeys

* nit

* Exclude nexted child fields

* add updates and show failing testcases

* working

* add more tests

* even more test cases

* use await for added tests

* lint

* Add suggestions
This commit is contained in:
Corey
2021-06-03 15:54:44 -04:00
committed by GitHub
parent 5abbeeb8d1
commit 6d13aeae2c
4 changed files with 581 additions and 97 deletions

View File

@@ -38,7 +38,6 @@ function RestQuery(
this.response = null;
this.findOptions = {};
this.context = context || {};
if (!this.auth.isMaster) {
if (this.className == '_Session') {
if (!this.auth.user) {
@@ -69,11 +68,22 @@ function RestQuery(
// For example, passing an arg of include=foo.bar,foo.baz could lead to
// this.include = [['foo'], ['foo', 'baz'], ['foo', 'bar']]
this.include = [];
let keysForInclude = '';
// If we have keys, we probably want to force some includes (n-1 level)
// See issue: https://github.com/parse-community/parse-server/issues/3185
if (Object.prototype.hasOwnProperty.call(restOptions, 'keys')) {
const keysForInclude = restOptions.keys
keysForInclude = restOptions.keys;
}
// If we have keys, we probably want to force some includes (n-1 level)
// in order to exclude specific keys.
if (Object.prototype.hasOwnProperty.call(restOptions, 'excludeKeys')) {
keysForInclude += ',' + restOptions.excludeKeys;
}
if (keysForInclude.length > 0) {
keysForInclude = keysForInclude
.split(',')
.filter(key => {
// At least 2 components
@@ -846,6 +856,26 @@ function includePath(config, auth, response, path, restOptions = {}) {
}
}
if (restOptions.excludeKeys) {
const excludeKeys = new Set(restOptions.excludeKeys.split(','));
const excludeKeySet = Array.from(excludeKeys).reduce((set, key) => {
const keyPath = key.split('.');
let i = 0;
for (i; i < path.length; i++) {
if (path[i] != keyPath[i]) {
return set;
}
}
if (i == (keyPath.length - 1)) {
set.add(keyPath[i]);
}
return set;
}, new Set());
if (excludeKeySet.size > 0) {
includeRestOptions.excludeKeys = Array.from(excludeKeySet).join(',');
}
}
if (restOptions.includeReadPreference) {
includeRestOptions.readPreference = restOptions.includeReadPreference;
includeRestOptions.includeReadPreference = restOptions.includeReadPreference;