From d5e1c9f6d90e3c29a9b9e5cde50ede4fc9fc7106 Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Thu, 4 Mar 2021 22:50:37 -0500 Subject: [PATCH 01/23] fix keys and excludeKeys to work with JSON array strings --- spec/ParseQuery.spec.js | 13 ++++++++++--- src/Routers/ClassesRouter.js | 16 ++++++++-------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index 085d178ab2..f34869e557 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -3140,7 +3140,7 @@ describe('Parse.Query testing', () => { }); it('select keys query', function (done) { - const obj = new TestObject({ foo: 'baz', bar: 1 }); + const obj = new TestObject({ foo: 'baz', bar: 1, qux: 2 }); obj .save() @@ -3157,23 +3157,28 @@ describe('Parse.Query testing', () => { ok(!result.dirty(), 'expected result not to be dirty'); strictEqual(result.get('foo'), 'baz'); strictEqual(result.get('bar'), undefined, "expected 'bar' field to be unset"); + strictEqual(result.get('qux'), undefined, "expected 'qux' field to be unset"); return result.fetch(); }) .then(function (result) { strictEqual(result.get('foo'), 'baz'); strictEqual(result.get('bar'), 1); + strictEqual(result.get('qux'), 2); }) .then(function () { obj._clearServerData(); const query = new Parse.Query(TestObject); - query.select([]); + query.select(['foo']); return query.first(); }) .then(function (result) { ok(result.id, 'expected object id to be set'); + ok(result.createdAt, 'expected object createdAt to be set'); + ok(result.updatedAt, 'expected object updatedAt to be set'); ok(!result.dirty(), 'expected result not to be dirty'); - strictEqual(result.get('foo'), undefined, "expected 'foo' field to be unset"); + strictEqual(result.get('foo'), 'baz'); strictEqual(result.get('bar'), undefined, "expected 'bar' field to be unset"); + strictEqual(result.get('qux'), undefined, "expected 'qux' field to be unset"); }) .then(function () { obj._clearServerData(); @@ -3186,6 +3191,7 @@ describe('Parse.Query testing', () => { ok(!result.dirty(), 'expected result not to be dirty'); strictEqual(result.get('foo'), 'baz'); strictEqual(result.get('bar'), 1); + strictEqual(result.get('qux'), undefined, "expected 'qux' field to be unset"); }) .then(function () { obj._clearServerData(); @@ -3198,6 +3204,7 @@ describe('Parse.Query testing', () => { ok(!result.dirty(), 'expected result not to be dirty'); strictEqual(result.get('foo'), 'baz'); strictEqual(result.get('bar'), 1); + strictEqual(result.get('qux'), undefined, "expected 'qux' field to be unset"); }) .then( function () { diff --git a/src/Routers/ClassesRouter.js b/src/Routers/ClassesRouter.js index d1fc13bc02..a7c8f2b285 100644 --- a/src/Routers/ClassesRouter.js +++ b/src/Routers/ClassesRouter.js @@ -57,14 +57,14 @@ export class ClassesRouter extends PromiseRouter { } } - if (typeof body.keys === 'string') { - options.keys = body.keys; + if (body.keys) { + options.keys = String(body.keys); } if (body.include) { options.include = String(body.include); } - if (typeof body.excludeKeys == 'string') { - options.excludeKeys = body.excludeKeys; + if (body.excludeKeys) { + options.excludeKeys = String(body.excludeKeys); } if (typeof body.readPreference === 'string') { options.readPreference = body.readPreference; @@ -187,11 +187,11 @@ export class ClassesRouter extends PromiseRouter { if (body.count) { options.count = true; } - if (typeof body.keys == 'string') { - options.keys = body.keys; + if (body.keys) { + options.keys = String(body.keys); } - if (typeof body.excludeKeys == 'string') { - options.excludeKeys = body.excludeKeys; + if (body.excludeKeys) { + options.excludeKeys = String(body.excludeKeys); } if (body.include) { options.include = String(body.include); From 65a109a196f817630a9f786b06e88a0455e9f5af Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Thu, 4 Mar 2021 22:59:01 -0500 Subject: [PATCH 02/23] make excludeKeys test more robust --- spec/ParseQuery.spec.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index f34869e557..f341e6320f 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -3231,6 +3231,17 @@ describe('Parse.Query testing', () => { }); expect(response.data.results[0].foo).toBeUndefined(); expect(response.data.results[0].hello).toBe('world'); + + const response2 = await request({ + url: Parse.serverURL + '/classes/TestObject', + qs: { + excludeKeys: ['foo', 'hello'], + where: JSON.stringify({ objectId: obj.id }), + }, + headers: masterKeyHeaders, + }); + expect(response2.data.results[0].foo).toBeUndefined(); + expect(response2.data.results[0].hello).toBeUndefined(); }); it('exclude keys with select same key', async () => { From 5640cd535487f74664f11ea95166ab3fa78d9f95 Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Fri, 5 Mar 2021 08:50:00 -0500 Subject: [PATCH 03/23] add changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38cd9fa871..c1610399c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ __BREAKING CHANGES:__ - NEW: Added file upload restriction. File upload is now only allowed for authenticated users by default for improved security. To allow file upload also for Anonymous Users or Public, set the `fileUpload` parameter in the [Parse Server Options](https://parseplatform.org/parse-server/api/master/ParseServerOptions.html). [#7071](https://github.com/parse-community/parse-server/pull/7071). Thanks to [dblythy](https://github.com/dblythy), [Manuel Trezza](https://github.com/mtrezza). +- FIX: select and excludeKey queries to properly accept JSON arrays. If you use `select()` or `select([])`, they may not work as they previously did as you will receive all keys instead of only receiving the default Parse keys, `createdAt`, `objectId`, etc. [#7242](https://github.com/parse-community/parse-server/pull/7242). Thanks to [Corey Baker](https://github.com/cbaker6). ___ - FIX: Move graphql-tag from devDependencies to dependencies. [7183](https://github.com/parse-community/parse-server/pull/7183). Thanks to [Antonio Davi Macedo Coelho de Castro](https://github.com/davimacedo). - IMPROVE: Allow Cloud Validator `options` to be async [#7155](https://github.com/parse-community/parse-server/pull/7155). Thanks to [dblythy](https://github.com/dblythy) From c300e4d9ae0d26b6d8b089d7275c6b6bc6daa281 Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Fri, 5 Mar 2021 12:36:04 -0500 Subject: [PATCH 04/23] add select([]) functionality to fix) --- spec/ParseQuery.spec.js | 15 +++++++++++++++ src/Routers/ClassesRouter.js | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index f341e6320f..5112b120dd 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -3165,6 +3165,21 @@ describe('Parse.Query testing', () => { strictEqual(result.get('bar'), 1); strictEqual(result.get('qux'), 2); }) + .then(function () { + obj._clearServerData(); + const query = new Parse.Query(TestObject); + query.select([]); + return query.first(); + }) + .then(function (result) { + ok(result.id, 'expected object id to be set'); + ok(result.createdAt, 'expected object createdAt to be set'); + ok(result.updatedAt, 'expected object updatedAt to be set'); + ok(!result.dirty(), 'expected result not to be dirty'); + strictEqual(result.get('foo'), undefined, "expected 'foo' field to be unset"); + strictEqual(result.get('bar'), undefined, "expected 'bar' field to be unset"); + strictEqual(result.get('qux'), undefined, "expected 'qux' field to be unset"); + }) .then(function () { obj._clearServerData(); const query = new Parse.Query(TestObject); diff --git a/src/Routers/ClassesRouter.js b/src/Routers/ClassesRouter.js index a7c8f2b285..55473fa337 100644 --- a/src/Routers/ClassesRouter.js +++ b/src/Routers/ClassesRouter.js @@ -187,7 +187,7 @@ export class ClassesRouter extends PromiseRouter { if (body.count) { options.count = true; } - if (body.keys) { + if (body.keys || body.keys === '') { options.keys = String(body.keys); } if (body.excludeKeys) { From 97103bdd9e611d0e829d02b3c2efc3c166ca68cd Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Fri, 5 Mar 2021 12:40:10 -0500 Subject: [PATCH 05/23] update changelog --- CHANGELOG.md | 2 +- src/Routers/ClassesRouter.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1610399c2..c3a9cc66d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,6 @@ __BREAKING CHANGES:__ - NEW: Added file upload restriction. File upload is now only allowed for authenticated users by default for improved security. To allow file upload also for Anonymous Users or Public, set the `fileUpload` parameter in the [Parse Server Options](https://parseplatform.org/parse-server/api/master/ParseServerOptions.html). [#7071](https://github.com/parse-community/parse-server/pull/7071). Thanks to [dblythy](https://github.com/dblythy), [Manuel Trezza](https://github.com/mtrezza). -- FIX: select and excludeKey queries to properly accept JSON arrays. If you use `select()` or `select([])`, they may not work as they previously did as you will receive all keys instead of only receiving the default Parse keys, `createdAt`, `objectId`, etc. [#7242](https://github.com/parse-community/parse-server/pull/7242). Thanks to [Corey Baker](https://github.com/cbaker6). ___ - FIX: Move graphql-tag from devDependencies to dependencies. [7183](https://github.com/parse-community/parse-server/pull/7183). Thanks to [Antonio Davi Macedo Coelho de Castro](https://github.com/davimacedo). - IMPROVE: Allow Cloud Validator `options` to be async [#7155](https://github.com/parse-community/parse-server/pull/7155). Thanks to [dblythy](https://github.com/dblythy) @@ -37,6 +36,7 @@ ___ - FIX: Fix error when a not yet inserted job is updated [#7196](https://github.com/parse-community/parse-server/pull/7196). Thanks to [Antonio Davi Macedo Coelho de Castro](https://github.com/davimacedo). - FIX: request.context for afterFind triggers. [#7078](https://github.com/parse-community/parse-server/pull/7078). Thanks to [dblythy](https://github.com/dblythy) - FIX: Winston Logger interpolating stdout to console [#7114](https://github.com/parse-community/parse-server/pull/7114). Thanks to [dplewis](https://github.com/dplewis) +- FIX: select and excludeKey queries to properly accept JSON string arrays [#7242](https://github.com/parse-community/parse-server/pull/7242). Thanks to [Corey Baker](https://github.com/cbaker6). ### 4.5.0 [Full Changelog](https://github.com/parse-community/parse-server/compare/4.4.0...4.5.0) diff --git a/src/Routers/ClassesRouter.js b/src/Routers/ClassesRouter.js index 55473fa337..66a046d49d 100644 --- a/src/Routers/ClassesRouter.js +++ b/src/Routers/ClassesRouter.js @@ -57,7 +57,7 @@ export class ClassesRouter extends PromiseRouter { } } - if (body.keys) { + if (body.keys || body.keys === '') { options.keys = String(body.keys); } if (body.include) { From c91142d249ad7a7735446f1df5259c1616da6447 Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Sat, 6 Mar 2021 17:32:14 -0500 Subject: [PATCH 06/23] update keys --- src/Routers/ClassesRouter.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Routers/ClassesRouter.js b/src/Routers/ClassesRouter.js index 66a046d49d..63166752e8 100644 --- a/src/Routers/ClassesRouter.js +++ b/src/Routers/ClassesRouter.js @@ -57,7 +57,7 @@ export class ClassesRouter extends PromiseRouter { } } - if (body.keys || body.keys === '') { + if (body.keys != null) { options.keys = String(body.keys); } if (body.include) { @@ -187,7 +187,7 @@ export class ClassesRouter extends PromiseRouter { if (body.count) { options.count = true; } - if (body.keys || body.keys === '') { + if (body.keys != null) { options.keys = String(body.keys); } if (body.excludeKeys) { From e8a14cfc4b231e57a97bc5197032ab43d36f7271 Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Sat, 6 Mar 2021 19:20:33 -0500 Subject: [PATCH 07/23] add exclude test --- spec/ParseQuery.spec.js | 14 ++++++++++++++ src/Routers/ClassesRouter.js | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index 5112b120dd..68e6ec9393 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -3257,6 +3257,20 @@ describe('Parse.Query testing', () => { }); expect(response2.data.results[0].foo).toBeUndefined(); expect(response2.data.results[0].hello).toBeUndefined(); + + const response3 = await request({ + url: Parse.serverURL + '/classes/TestObject', + qs: { + excludeKeys: [], + where: JSON.stringify({ objectId: obj.id }), + }, + headers: masterKeyHeaders, + }); + ok(response3.data.results[0].objectId, 'expected objectId to be set'); + ok(response3.data.results[0].createdAt, 'expected object createdAt to be set'); + ok(response3.data.results[0].updatedAt, 'expected object updatedAt to be set'); + expect(response3.data.results[0].foo).toBe('baz'); + expect(response3.data.results[0].hello).toBe('world'); }); it('exclude keys with select same key', async () => { diff --git a/src/Routers/ClassesRouter.js b/src/Routers/ClassesRouter.js index 63166752e8..8c2097b56b 100644 --- a/src/Routers/ClassesRouter.js +++ b/src/Routers/ClassesRouter.js @@ -63,7 +63,7 @@ export class ClassesRouter extends PromiseRouter { if (body.include) { options.include = String(body.include); } - if (body.excludeKeys) { + if (body.excludeKeys != null) { options.excludeKeys = String(body.excludeKeys); } if (typeof body.readPreference === 'string') { @@ -190,7 +190,7 @@ export class ClassesRouter extends PromiseRouter { if (body.keys != null) { options.keys = String(body.keys); } - if (body.excludeKeys) { + if (body.excludeKeys != null) { options.excludeKeys = String(body.excludeKeys); } if (body.include) { From e98d6898b2b34d5eb8d611c223aff7895e001f22 Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Sat, 6 Mar 2021 19:51:42 -0500 Subject: [PATCH 08/23] add select REST test and exclude JS SDK test --- spec/ParseQuery.spec.js | 136 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 135 insertions(+), 1 deletion(-) diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index 68e6ec9393..e90e86cd5e 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -3139,7 +3139,7 @@ describe('Parse.Query testing', () => { ); }); - it('select keys query', function (done) { + it('select keys query JS SDK', function (done) { const obj = new TestObject({ foo: 'baz', bar: 1, qux: 2 }); obj @@ -3232,6 +3232,47 @@ describe('Parse.Query testing', () => { ); }); + it('select keys', async () => { + const obj = new TestObject({ foo: 'baz', hello: 'world' }); + await obj.save(); + + const response = await request({ + url: Parse.serverURL + '/classes/TestObject', + qs: { + keys: 'hello', + where: JSON.stringify({ objectId: obj.id }), + }, + headers: masterKeyHeaders, + }); + expect(response.data.results[0].foo).toBeUndefined(); + expect(response.data.results[0].hello).toBe('world'); + + const response2 = await request({ + url: Parse.serverURL + '/classes/TestObject', + qs: { + keys: ['foo', 'hello'], + where: JSON.stringify({ objectId: obj.id }), + }, + headers: masterKeyHeaders, + }); + expect(response2.data.results[0].foo).toBe('baz'); + expect(response2.data.results[0].hello).toBe('world'); + + const response3 = await request({ + url: Parse.serverURL + '/classes/TestObject', + qs: { + keys: [''], + where: JSON.stringify({ objectId: obj.id }), + }, + headers: masterKeyHeaders, + }); + ok(response3.data.results[0].objectId, 'expected objectId to be set'); + ok(response3.data.results[0].createdAt, 'expected object createdAt to be set'); + ok(response3.data.results[0].updatedAt, 'expected object updatedAt to be set'); + expect(response3.data.results[0].foo).toBeUndefined(); + expect(response3.data.results[0].hello).toBeUndefined(); + }); + it('exclude keys', async () => { const obj = new TestObject({ foo: 'baz', hello: 'world' }); await obj.save(); @@ -3273,6 +3314,99 @@ describe('Parse.Query testing', () => { expect(response3.data.results[0].hello).toBe('world'); }); + it('exclude keys query JS SDK', function (done) { + const obj = new TestObject({ foo: 'baz', bar: 1, qux: 2 }); + + obj + .save() + .then(function () { + obj._clearServerData(); + const query = new Parse.Query(TestObject); + query.exclude('foo'); + return query.first(); + }) + .then(function (result) { + ok(result.id, 'expected object id to be set'); + ok(result.createdAt, 'expected object createdAt to be set'); + ok(result.updatedAt, 'expected object updatedAt to be set'); + ok(!result.dirty(), 'expected result not to be dirty'); + strictEqual(result.get('foo'), undefined, "expected 'bar' field to be unset"); + strictEqual(result.get('bar'), 1); + strictEqual(result.get('qux'), 2); + return result.fetch(); + }) + .then(function (result) { + strictEqual(result.get('foo'), 'baz'); + strictEqual(result.get('bar'), 1); + strictEqual(result.get('qux'), 2); + }) + .then(function () { + obj._clearServerData(); + const query = new Parse.Query(TestObject); + query.exclude([]); + return query.first(); + }) + .then(function (result) { + ok(result.id, 'expected object id to be set'); + ok(result.createdAt, 'expected object createdAt to be set'); + ok(result.updatedAt, 'expected object updatedAt to be set'); + ok(!result.dirty(), 'expected result not to be dirty'); + strictEqual(result.get('foo'), 'baz'); + strictEqual(result.get('bar'), 1); + strictEqual(result.get('qux'), 2); + }) + .then(function () { + obj._clearServerData(); + const query = new Parse.Query(TestObject); + query.exclude(['foo']); + return query.first(); + }) + .then(function (result) { + ok(result.id, 'expected object id to be set'); + ok(result.createdAt, 'expected object createdAt to be set'); + ok(result.updatedAt, 'expected object updatedAt to be set'); + ok(!result.dirty(), 'expected result not to be dirty'); + strictEqual(result.get('foo'), undefined, "expected 'bar' field to be unset"); + strictEqual(result.get('bar'), 1); + strictEqual(result.get('qux'), 2); + }) + .then(function () { + obj._clearServerData(); + const query = new Parse.Query(TestObject); + query.exclude(['foo', 'bar']); + return query.first(); + }) + .then(function (result) { + ok(result.id, 'expected object id to be set'); + ok(!result.dirty(), 'expected result not to be dirty'); + strictEqual(result.get('foo'), undefined, "expected 'bar' field to be unset"); + strictEqual(result.get('bar'), undefined, "expected 'bar' field to be unset"); + strictEqual(result.get('qux'), 2); + }) + .then(function () { + obj._clearServerData(); + const query = new Parse.Query(TestObject); + query.exclude('foo', 'bar'); + return query.first(); + }) + .then(function (result) { + ok(result.id, 'expected object id to be set'); + ok(!result.dirty(), 'expected result not to be dirty'); + strictEqual(result.get('foo'), undefined, "expected 'bar' field to be unset"); + strictEqual(result.get('bar'), undefined, "expected 'bar' field to be unset"); + strictEqual(result.get('qux'), 2); + }) + .then( + function () { + done(); + }, + function (err) { + ok(false, 'other error: ' + JSON.stringify(err)); + done(); + } + ); + }); + it('exclude keys with select same key', async () => { const obj = new TestObject({ foo: 'baz', hello: 'world' }); await obj.save(); From e97398cef6fa911d42acad6ff7b21eb7861d68db Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Sun, 7 Mar 2021 10:19:12 -0500 Subject: [PATCH 09/23] add more tests --- spec/ParseQuery.spec.js | 96 ++++++++++++++++++++++++++--------------- 1 file changed, 62 insertions(+), 34 deletions(-) diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index e90e86cd5e..f8f0de9a89 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -3271,47 +3271,20 @@ describe('Parse.Query testing', () => { ok(response3.data.results[0].updatedAt, 'expected object updatedAt to be set'); expect(response3.data.results[0].foo).toBeUndefined(); expect(response3.data.results[0].hello).toBeUndefined(); - }); - - it('exclude keys', async () => { - const obj = new TestObject({ foo: 'baz', hello: 'world' }); - await obj.save(); - const response = await request({ + const response4 = await request({ url: Parse.serverURL + '/classes/TestObject', qs: { - excludeKeys: 'foo', + keys: [], where: JSON.stringify({ objectId: obj.id }), }, headers: masterKeyHeaders, }); - expect(response.data.results[0].foo).toBeUndefined(); - expect(response.data.results[0].hello).toBe('world'); - - const response2 = await request({ - url: Parse.serverURL + '/classes/TestObject', - qs: { - excludeKeys: ['foo', 'hello'], - where: JSON.stringify({ objectId: obj.id }), - }, - headers: masterKeyHeaders, - }); - expect(response2.data.results[0].foo).toBeUndefined(); - expect(response2.data.results[0].hello).toBeUndefined(); - - const response3 = await request({ - url: Parse.serverURL + '/classes/TestObject', - qs: { - excludeKeys: [], - where: JSON.stringify({ objectId: obj.id }), - }, - headers: masterKeyHeaders, - }); - ok(response3.data.results[0].objectId, 'expected objectId to be set'); - ok(response3.data.results[0].createdAt, 'expected object createdAt to be set'); - ok(response3.data.results[0].updatedAt, 'expected object updatedAt to be set'); - expect(response3.data.results[0].foo).toBe('baz'); - expect(response3.data.results[0].hello).toBe('world'); + ok(response4.data.results[0].objectId, 'expected objectId to be set'); + ok(response4.data.results[0].createdAt, 'expected object createdAt to be set'); + ok(response4.data.results[0].updatedAt, 'expected object updatedAt to be set'); + expect(response4.data.results[0].foo).toBe('baz'); + expect(response4.data.results[0].hello).toBe('world'); }); it('exclude keys query JS SDK', function (done) { @@ -3407,6 +3380,61 @@ describe('Parse.Query testing', () => { ); }); + it('exclude keys', async () => { + const obj = new TestObject({ foo: 'baz', hello: 'world' }); + await obj.save(); + + const response = await request({ + url: Parse.serverURL + '/classes/TestObject', + qs: { + excludeKeys: 'foo', + where: JSON.stringify({ objectId: obj.id }), + }, + headers: masterKeyHeaders, + }); + expect(response.data.results[0].foo).toBeUndefined(); + expect(response.data.results[0].hello).toBe('world'); + + const response2 = await request({ + url: Parse.serverURL + '/classes/TestObject', + qs: { + excludeKeys: ['foo', 'hello'], + where: JSON.stringify({ objectId: obj.id }), + }, + headers: masterKeyHeaders, + }); + expect(response2.data.results[0].foo).toBeUndefined(); + expect(response2.data.results[0].hello).toBeUndefined(); + + const response3 = await request({ + url: Parse.serverURL + '/classes/TestObject', + qs: { + excludeKeys: [], + where: JSON.stringify({ objectId: obj.id }), + }, + headers: masterKeyHeaders, + }); + ok(response3.data.results[0].objectId, 'expected objectId to be set'); + ok(response3.data.results[0].createdAt, 'expected object createdAt to be set'); + ok(response3.data.results[0].updatedAt, 'expected object updatedAt to be set'); + expect(response3.data.results[0].foo).toBe('baz'); + expect(response3.data.results[0].hello).toBe('world'); + + const response4 = await request({ + url: Parse.serverURL + '/classes/TestObject', + qs: { + excludeKeys: [''], + where: JSON.stringify({ objectId: obj.id }), + }, + headers: masterKeyHeaders, + }); + ok(response4.data.results[0].objectId, 'expected objectId to be set'); + ok(response4.data.results[0].createdAt, 'expected object createdAt to be set'); + ok(response4.data.results[0].updatedAt, 'expected object updatedAt to be set'); + expect(response4.data.results[0].foo).toBe('baz'); + expect(response4.data.results[0].hello).toBe('world'); + }); + it('exclude keys with select same key', async () => { const obj = new TestObject({ foo: 'baz', hello: 'world' }); await obj.save(); From c0584517ddf5cc9a51e730104ff61aab38f1ec2c Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Sun, 7 Mar 2021 11:20:39 -0500 Subject: [PATCH 10/23] add additional exclude test --- spec/ParseQuery.spec.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index f8f0de9a89..be86a02a00 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -3285,6 +3285,20 @@ describe('Parse.Query testing', () => { ok(response4.data.results[0].updatedAt, 'expected object updatedAt to be set'); expect(response4.data.results[0].foo).toBe('baz'); expect(response4.data.results[0].hello).toBe('world'); + + const response5 = await request({ + url: Parse.serverURL + '/classes/TestObject', + qs: { + keys: '', + where: JSON.stringify({ objectId: obj.id }), + }, + headers: masterKeyHeaders, + }); + ok(response5.data.results[0].objectId, 'expected objectId to be set'); + ok(response5.data.results[0].createdAt, 'expected object createdAt to be set'); + ok(response5.data.results[0].updatedAt, 'expected object updatedAt to be set'); + expect(response5.data.results[0].foo).toBeUndefined(); + expect(response5.data.results[0].hello).toBeUndefined(); }); it('exclude keys query JS SDK', function (done) { @@ -3433,6 +3447,20 @@ describe('Parse.Query testing', () => { ok(response4.data.results[0].updatedAt, 'expected object updatedAt to be set'); expect(response4.data.results[0].foo).toBe('baz'); expect(response4.data.results[0].hello).toBe('world'); + + const response5 = await request({ + url: Parse.serverURL + '/classes/TestObject', + qs: { + excludeKeys: '', + where: JSON.stringify({ objectId: obj.id }), + }, + headers: masterKeyHeaders, + }); + ok(response5.data.results[0].objectId, 'expected objectId to be set'); + ok(response5.data.results[0].createdAt, 'expected object createdAt to be set'); + ok(response5.data.results[0].updatedAt, 'expected object updatedAt to be set'); + expect(response5.data.results[0].foo).toBe('baz'); + expect(response5.data.results[0].hello).toBe('world'); }); it('exclude keys with select same key', async () => { From 0b72a7a8181b3d86aff70076abf3630d421d08d8 Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Sun, 7 Mar 2021 11:36:34 -0500 Subject: [PATCH 11/23] improved select test for testing JSON string array in REST --- spec/ParseQuery.spec.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index be86a02a00..572e5d647d 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -3233,7 +3233,7 @@ describe('Parse.Query testing', () => { }); it('select keys', async () => { - const obj = new TestObject({ foo: 'baz', hello: 'world' }); + const obj = new TestObject({ foo: 'baz', bar: 1, hello: 'world' }); await obj.save(); const response = await request({ @@ -3245,6 +3245,7 @@ describe('Parse.Query testing', () => { headers: masterKeyHeaders, }); expect(response.data.results[0].foo).toBeUndefined(); + expect(response.data.results[0].bar).toBeUndefined(); expect(response.data.results[0].hello).toBe('world'); const response2 = await request({ @@ -3256,6 +3257,7 @@ describe('Parse.Query testing', () => { headers: masterKeyHeaders, }); expect(response2.data.results[0].foo).toBe('baz'); + expect(response2.data.results[0].bar).toBeUndefined(); expect(response2.data.results[0].hello).toBe('world'); const response3 = await request({ @@ -3270,6 +3272,7 @@ describe('Parse.Query testing', () => { ok(response3.data.results[0].createdAt, 'expected object createdAt to be set'); ok(response3.data.results[0].updatedAt, 'expected object updatedAt to be set'); expect(response3.data.results[0].foo).toBeUndefined(); + expect(response3.data.results[0].bar).toBeUndefined(); expect(response3.data.results[0].hello).toBeUndefined(); const response4 = await request({ @@ -3284,6 +3287,7 @@ describe('Parse.Query testing', () => { ok(response4.data.results[0].createdAt, 'expected object createdAt to be set'); ok(response4.data.results[0].updatedAt, 'expected object updatedAt to be set'); expect(response4.data.results[0].foo).toBe('baz'); + expect(response4.data.results[0].bar).toBe(1); expect(response4.data.results[0].hello).toBe('world'); const response5 = await request({ @@ -3298,7 +3302,20 @@ describe('Parse.Query testing', () => { ok(response5.data.results[0].createdAt, 'expected object createdAt to be set'); ok(response5.data.results[0].updatedAt, 'expected object updatedAt to be set'); expect(response5.data.results[0].foo).toBeUndefined(); + expect(response5.data.results[0].bar).toBeUndefined(); expect(response5.data.results[0].hello).toBeUndefined(); + + const response6 = await request({ + url: Parse.serverURL + '/classes/TestObject', + qs: { + keys: '["foo", "hello"]', + where: JSON.stringify({ objectId: obj.id }), + }, + headers: masterKeyHeaders, + }); + expect(response6.data.results[0].foo).toBe('baz'); + expect(response6.data.results[0].bar).toBeUndefined(); + expect(response6.data.results[0].hello).toBe('world'); }); it('exclude keys query JS SDK', function (done) { From 8e15e909b43537b85af60c76e1cc38ddca9461c7 Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Sun, 7 Mar 2021 11:52:18 -0500 Subject: [PATCH 12/23] improved exclude test for testing JSON string array in REST --- spec/ParseQuery.spec.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index 572e5d647d..8d2b188dba 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -3478,6 +3478,28 @@ describe('Parse.Query testing', () => { ok(response5.data.results[0].updatedAt, 'expected object updatedAt to be set'); expect(response5.data.results[0].foo).toBe('baz'); expect(response5.data.results[0].hello).toBe('world'); + + const response6 = await request({ + url: Parse.serverURL + '/classes/TestObject', + qs: { + excludeKeys: '["hello"]', + where: JSON.stringify({ objectId: obj.id }), + }, + headers: masterKeyHeaders, + }); + expect(response6.data.results[0].foo).toBe('baz'); + expect(response6.data.results[0].hello).toBeUndefined(); + + const response7 = await request({ + url: Parse.serverURL + '/classes/TestObject', + qs: { + excludeKeys: '["foo", "hello"]', + where: JSON.stringify({ objectId: obj.id }), + }, + headers: masterKeyHeaders, + }); + expect(response7.data.results[0].foo).toBeUndefined(); + expect(response7.data.results[0].hello).toBeUndefined(); }); it('exclude keys with select same key', async () => { From a05b56f83516a3fd48587e0e3b213d0fc05d5207 Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Sun, 7 Mar 2021 14:12:12 -0500 Subject: [PATCH 13/23] check for parse keys --- spec/ParseQuery.spec.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index 8d2b188dba..aa1ea4a29f 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -3313,6 +3313,9 @@ describe('Parse.Query testing', () => { }, headers: masterKeyHeaders, }); + ok(response6.data.results[0].objectId, 'expected objectId to be set'); + ok(response6.data.results[0].createdAt, 'expected object createdAt to be set'); + ok(response6.data.results[0].updatedAt, 'expected object updatedAt to be set'); expect(response6.data.results[0].foo).toBe('baz'); expect(response6.data.results[0].bar).toBeUndefined(); expect(response6.data.results[0].hello).toBe('world'); @@ -3423,6 +3426,9 @@ describe('Parse.Query testing', () => { }, headers: masterKeyHeaders, }); + ok(response.data.results[0].objectId, 'expected objectId to be set'); + ok(response.data.results[0].createdAt, 'expected object createdAt to be set'); + ok(response.data.results[0].updatedAt, 'expected object updatedAt to be set'); expect(response.data.results[0].foo).toBeUndefined(); expect(response.data.results[0].hello).toBe('world'); @@ -3434,6 +3440,9 @@ describe('Parse.Query testing', () => { }, headers: masterKeyHeaders, }); + ok(response2.data.results[0].objectId, 'expected objectId to be set'); + ok(response2.data.results[0].createdAt, 'expected object createdAt to be set'); + ok(response2.data.results[0].updatedAt, 'expected object updatedAt to be set'); expect(response2.data.results[0].foo).toBeUndefined(); expect(response2.data.results[0].hello).toBeUndefined(); @@ -3487,6 +3496,9 @@ describe('Parse.Query testing', () => { }, headers: masterKeyHeaders, }); + ok(response6.data.results[0].objectId, 'expected objectId to be set'); + ok(response6.data.results[0].createdAt, 'expected object createdAt to be set'); + ok(response6.data.results[0].updatedAt, 'expected object updatedAt to be set'); expect(response6.data.results[0].foo).toBe('baz'); expect(response6.data.results[0].hello).toBeUndefined(); @@ -3498,6 +3510,9 @@ describe('Parse.Query testing', () => { }, headers: masterKeyHeaders, }); + ok(response7.data.results[0].objectId, 'expected objectId to be set'); + ok(response7.data.results[0].createdAt, 'expected object createdAt to be set'); + ok(response7.data.results[0].updatedAt, 'expected object updatedAt to be set'); expect(response7.data.results[0].foo).toBeUndefined(); expect(response7.data.results[0].hello).toBeUndefined(); }); From a722ae02d1e772b790f64243c996cb8c5f216137 Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Tue, 9 Mar 2021 12:52:17 -0500 Subject: [PATCH 14/23] make include look like keys and excludeKeys --- spec/ParseQuery.spec.js | 48 ++++++++++++++++++++++++++++++++++++ src/Routers/ClassesRouter.js | 4 +-- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index aa1ea4a29f..dcc9fa7949 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -4222,6 +4222,30 @@ describe('Parse.Query testing', () => { equal(result.child3.name, 'mo'); }); + it('include with [*]', async () => { + const child1 = new TestObject({ foo: 'bar', name: 'ac' }); + const child2 = new TestObject({ foo: 'baz', name: 'flo' }); + const child3 = new TestObject({ foo: 'bad', name: 'mo' }); + const parent = new Container({ child1, child2, child3 }); + await Parse.Object.saveAll([parent, child1, child2, child3]); + const options = Object.assign({}, masterKeyOptions, { + qs: { + where: JSON.stringify({ objectId: parent.id }), + include: '["*"]', + }, + }); + const resp = await request( + Object.assign({ url: Parse.serverURL + '/classes/Container' }, options) + ); + const result = resp.data.results[0]; + equal(result.child1.foo, 'bar'); + equal(result.child2.foo, 'baz'); + equal(result.child3.foo, 'bad'); + equal(result.child1.name, 'ac'); + equal(result.child2.name, 'flo'); + equal(result.child3.name, 'mo'); + }); + it('include with * overrides', async () => { const child1 = new TestObject({ foo: 'bar', name: 'ac' }); const child2 = new TestObject({ foo: 'baz', name: 'flo' }); @@ -4246,6 +4270,30 @@ describe('Parse.Query testing', () => { equal(result.child3.name, 'mo'); }); + it('include with ["*"] overrides', async () => { + const child1 = new TestObject({ foo: 'bar', name: 'ac' }); + const child2 = new TestObject({ foo: 'baz', name: 'flo' }); + const child3 = new TestObject({ foo: 'bad', name: 'mo' }); + const parent = new Container({ child1, child2, child3 }); + await Parse.Object.saveAll([parent, child1, child2, child3]); + const options = Object.assign({}, masterKeyOptions, { + qs: { + where: JSON.stringify({ objectId: parent.id }), + include: '["child2","*"]', + }, + }); + const resp = await request( + Object.assign({ url: Parse.serverURL + '/classes/Container' }, options) + ); + const result = resp.data.results[0]; + equal(result.child1.foo, 'bar'); + equal(result.child2.foo, 'baz'); + equal(result.child3.foo, 'bad'); + equal(result.child1.name, 'ac'); + equal(result.child2.name, 'flo'); + equal(result.child3.name, 'mo'); + }); + it('includeAll', done => { const child1 = new TestObject({ foo: 'bar', name: 'ac' }); const child2 = new TestObject({ foo: 'baz', name: 'flo' }); diff --git a/src/Routers/ClassesRouter.js b/src/Routers/ClassesRouter.js index 8c2097b56b..6788d93e5f 100644 --- a/src/Routers/ClassesRouter.js +++ b/src/Routers/ClassesRouter.js @@ -60,7 +60,7 @@ export class ClassesRouter extends PromiseRouter { if (body.keys != null) { options.keys = String(body.keys); } - if (body.include) { + if (body.include != null) { options.include = String(body.include); } if (body.excludeKeys != null) { @@ -193,7 +193,7 @@ export class ClassesRouter extends PromiseRouter { if (body.excludeKeys != null) { options.excludeKeys = String(body.excludeKeys); } - if (body.include) { + if (body.include != null) { options.include = String(body.include); } if (body.includeAll) { From 855ecc6ec7302b7736627b956612cad6cb9bb0c9 Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Tue, 9 Mar 2021 14:26:53 -0500 Subject: [PATCH 15/23] nit --- spec/ParseQuery.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index dcc9fa7949..5a1336eacd 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -4222,7 +4222,7 @@ describe('Parse.Query testing', () => { equal(result.child3.name, 'mo'); }); - it('include with [*]', async () => { + it('include with ["*"]', async () => { const child1 = new TestObject({ foo: 'bar', name: 'ac' }); const child2 = new TestObject({ foo: 'baz', name: 'flo' }); const child3 = new TestObject({ foo: 'bad', name: 'mo' }); From 02fa52b565dae0cb13bb00648c40bc6ec49c7543 Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Wed, 10 Mar 2021 12:17:17 -0500 Subject: [PATCH 16/23] Exclude nexted child fields --- spec/ParseQuery.spec.js | 71 +++++++++++++++++++++++++++++++++++++++-- src/RestQuery.js | 45 ++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 3 deletions(-) diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index 5a1336eacd..90d81e5976 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -4141,7 +4141,6 @@ describe('Parse.Query testing', () => { }) .then(function (savedFoobar) { const foobarQuery = new Parse.Query('Foobar'); - foobarQuery.include('barBaz'); foobarQuery.select(['fizz', 'barBaz.key']); foobarQuery.get(savedFoobar.id).then(function (foobarObj) { equal(foobarObj.get('fizz'), 'buzz'); @@ -4179,8 +4178,6 @@ describe('Parse.Query testing', () => { }) .then(function (savedFoobar) { const foobarQuery = new Parse.Query('Foobar'); - foobarQuery.include('barBaz'); - foobarQuery.include('barBaz.bazoo'); foobarQuery.select(['fizz', 'barBaz.key', 'barBaz.bazoo.some']); foobarQuery.get(savedFoobar.id).then(function (foobarObj) { equal(foobarObj.get('fizz'), 'buzz'); @@ -4198,6 +4195,74 @@ describe('Parse.Query testing', () => { }); }); + it('exclude nested keys', function (done) { + const Foobar = new Parse.Object('Foobar'); + const BarBaz = new Parse.Object('Barbaz'); + BarBaz.set('key', 'value'); + BarBaz.set('otherKey', 'value'); + BarBaz.save() + .then(() => { + Foobar.set('foo', 'bar'); + Foobar.set('fizz', 'buzz'); + Foobar.set('barBaz', BarBaz); + return Foobar.save(); + }) + .then(function (savedFoobar) { + const foobarQuery = new Parse.Query('Foobar'); + foobarQuery.exclude(['foo', 'barBaz.otherKey']); + foobarQuery.get(savedFoobar.id).then(function (foobarObj) { + equal(foobarObj.get('fizz'), 'buzz'); + equal(foobarObj.get('foo'), undefined); + if (foobarObj.has('barBaz')) { + equal(foobarObj.get('barBaz').get('key'), 'value'); + equal(foobarObj.get('barBaz').get('otherKey'), undefined); + } else { + fail('barBaz should be set'); + } + done(); + }); + }); + }); + + it('exclude nested keys 2 level', function (done) { + const Foobar = new Parse.Object('Foobar'); + const BarBaz = new Parse.Object('Barbaz'); + const Bazoo = new Parse.Object('Bazoo'); + + Bazoo.set('some', 'thing'); + Bazoo.set('otherSome', 'value'); + Bazoo.save() + .then(() => { + BarBaz.set('key', 'value'); + BarBaz.set('otherKey', 'value'); + BarBaz.set('bazoo', Bazoo); + return BarBaz.save(); + }) + .then(() => { + Foobar.set('foo', 'bar'); + Foobar.set('fizz', 'buzz'); + Foobar.set('barBaz', BarBaz); + return Foobar.save(); + }) + .then(function (savedFoobar) { + const foobarQuery = new Parse.Query('Foobar'); + foobarQuery.exclude(['foo', 'barBaz.otherKey', 'barBaz.bazoo.otherSome']); + foobarQuery.get(savedFoobar.id).then(function (foobarObj) { + equal(foobarObj.get('fizz'), 'buzz'); + equal(foobarObj.get('foo'), undefined); + if (foobarObj.has('barBaz')) { + equal(foobarObj.get('barBaz').get('key'), 'value'); + equal(foobarObj.get('barBaz').get('otherKey'), undefined); + equal(foobarObj.get('barBaz').get('bazoo').get('some'), 'thing'); + equal(foobarObj.get('barBaz').get('bazoo').get('otherSome'), undefined); + } else { + fail('barBaz should be set'); + } + done(); + }); + }); + }); + it('include with *', async () => { const child1 = new TestObject({ foo: 'bar', name: 'ac' }); const child2 = new TestObject({ foo: 'baz', name: 'flo' }); diff --git a/src/RestQuery.js b/src/RestQuery.js index 99025af464..ed3db2abef 100644 --- a/src/RestQuery.js +++ b/src/RestQuery.js @@ -97,6 +97,31 @@ function RestQuery( } } + if (Object.prototype.hasOwnProperty.call(restOptions, 'excludeKeys')) { + const keysForInclude = restOptions.excludeKeys + .split(',') + .filter(excludeKey => { + // At least 2 components + return excludeKey.split('.').length > 1; + }) + .map(excludeKey => { + // Slice the last component (a.b.c -> a.b) + // Otherwise we'll include one level too much. + return excludeKey.slice(0, excludeKey.lastIndexOf('.')); + }) + .join(','); + + // Concat the possibly present include string with the one from the keys + // Dedup / sorting is handle in 'include' case. + if (keysForInclude.length > 0) { + if (!restOptions.include || restOptions.include.length == 0) { + restOptions.include = keysForInclude; + } else { + restOptions.include += ',' + keysForInclude; + } + } + } + for (var option in restOptions) { switch (option) { case 'keys': { @@ -846,6 +871,26 @@ function includePath(config, auth, response, path, restOptions = {}) { } } + if (restOptions.excludeKeys) { + const keys = new Set(restOptions.excludeKeys.split(',')); + const keySet = Array.from(keys).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 (keySet.size > 0) { + includeRestOptions.excludeKeys = Array.from(keySet).join(','); + } + } + if (restOptions.includeReadPreference) { includeRestOptions.readPreference = restOptions.includeReadPreference; includeRestOptions.includeReadPreference = restOptions.includeReadPreference; From 521a5f57a504c764fbd0819b390523df34779468 Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Wed, 10 Mar 2021 17:03:21 -0500 Subject: [PATCH 17/23] add updates and show failing testcases --- src/RestQuery.js | 45 ++++++++++++++------------------------------- 1 file changed, 14 insertions(+), 31 deletions(-) diff --git a/src/RestQuery.js b/src/RestQuery.js index ed3db2abef..950635c67e 100644 --- a/src/RestQuery.js +++ b/src/RestQuery.js @@ -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,20 @@ 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 = []; + var 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 (Object.prototype.hasOwnProperty.call(restOptions, 'excludeKeys')) { + keysForInclude += ',' + restOptions.excludeKeys; + }*/ + + if (keysForInclude.length > 0) { + keysForInclude = keysForInclude .split(',') .filter(key => { // At least 2 components @@ -97,31 +105,6 @@ function RestQuery( } } - if (Object.prototype.hasOwnProperty.call(restOptions, 'excludeKeys')) { - const keysForInclude = restOptions.excludeKeys - .split(',') - .filter(excludeKey => { - // At least 2 components - return excludeKey.split('.').length > 1; - }) - .map(excludeKey => { - // Slice the last component (a.b.c -> a.b) - // Otherwise we'll include one level too much. - return excludeKey.slice(0, excludeKey.lastIndexOf('.')); - }) - .join(','); - - // Concat the possibly present include string with the one from the keys - // Dedup / sorting is handle in 'include' case. - if (keysForInclude.length > 0) { - if (!restOptions.include || restOptions.include.length == 0) { - restOptions.include = keysForInclude; - } else { - restOptions.include += ',' + keysForInclude; - } - } - } - for (var option in restOptions) { switch (option) { case 'keys': { @@ -872,8 +855,8 @@ function includePath(config, auth, response, path, restOptions = {}) { } if (restOptions.excludeKeys) { - const keys = new Set(restOptions.excludeKeys.split(',')); - const keySet = Array.from(keys).reduce((set, key) => { + 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++) { @@ -886,8 +869,8 @@ function includePath(config, auth, response, path, restOptions = {}) { } return set; }, new Set()); - if (keySet.size > 0) { - includeRestOptions.excludeKeys = Array.from(keySet).join(','); + if (excludeKeySet.size > 0) { + includeRestOptions.excludeKeys = Array.from(excludeKeySet).join(','); } } From 4de0acf0799117ba8cca152c740403a49c8a4e52 Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Wed, 10 Mar 2021 17:04:18 -0500 Subject: [PATCH 18/23] working --- src/RestQuery.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/RestQuery.js b/src/RestQuery.js index 950635c67e..3de17762fb 100644 --- a/src/RestQuery.js +++ b/src/RestQuery.js @@ -75,10 +75,10 @@ function RestQuery( if (Object.prototype.hasOwnProperty.call(restOptions, 'keys')) { keysForInclude = restOptions.keys; } - /* + if (Object.prototype.hasOwnProperty.call(restOptions, 'excludeKeys')) { keysForInclude += ',' + restOptions.excludeKeys; - }*/ + } if (keysForInclude.length > 0) { keysForInclude = keysForInclude From 151d674d23e07c9dd18c8130d8ddeb75e24853f3 Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Tue, 16 Mar 2021 09:13:32 -0400 Subject: [PATCH 19/23] add more tests --- spec/ParseQuery.spec.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index 905cc3764c..6c16c47424 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -3159,6 +3159,21 @@ describe('Parse.Query testing', () => { strictEqual(result.get('bar'), 1); strictEqual(result.get('qux'), 2); }) + .then(function () { + obj._clearServerData(); + const query = new Parse.Query(TestObject); + query.select(); + return query.first(); + }) + .then(function (result) { + ok(result.id, 'expected object id to be set'); + ok(result.createdAt, 'expected object createdAt to be set'); + ok(result.updatedAt, 'expected object updatedAt to be set'); + ok(!result.dirty(), 'expected result not to be dirty'); + strictEqual(result.get('foo'), undefined, "expected 'foo' field to be unset"); + strictEqual(result.get('bar'), undefined, "expected 'bar' field to be unset"); + strictEqual(result.get('qux'), undefined, "expected 'qux' field to be unset"); + }) .then(function () { obj._clearServerData(); const query = new Parse.Query(TestObject); @@ -3341,6 +3356,21 @@ describe('Parse.Query testing', () => { strictEqual(result.get('bar'), 1); strictEqual(result.get('qux'), 2); }) + .then(function () { + obj._clearServerData(); + const query = new Parse.Query(TestObject); + query.exclude(); + return query.first(); + }) + .then(function (result) { + ok(result.id, 'expected object id to be set'); + ok(result.createdAt, 'expected object createdAt to be set'); + ok(result.updatedAt, 'expected object updatedAt to be set'); + ok(!result.dirty(), 'expected result not to be dirty'); + strictEqual(result.get('foo'), 'baz'); + strictEqual(result.get('bar'), 1); + strictEqual(result.get('qux'), 2); + }) .then(function () { obj._clearServerData(); const query = new Parse.Query(TestObject); From 1e931afe3e777664c7a5486a3f9a3426cbe565cd Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Fri, 19 Mar 2021 10:39:28 -0400 Subject: [PATCH 20/23] even more test cases --- spec/ParseQuery.spec.js | 215 +++++++++++++++++++++++++++++----------- 1 file changed, 159 insertions(+), 56 deletions(-) diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index 6c16c47424..a858d12e66 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -3217,6 +3217,19 @@ describe('Parse.Query testing', () => { strictEqual(result.get('bar'), 1); strictEqual(result.get('qux'), undefined, "expected 'qux' field to be unset"); }) + .then(function () { + obj._clearServerData(); + const query = new Parse.Query(TestObject); + query.select(['foo', 'bar', 'qux']); + return query.first(); + }) + .then(function (result) { + ok(result.id, 'expected object id to be set'); + ok(!result.dirty(), 'expected result not to be dirty'); + strictEqual(result.get('foo'), 'baz'); + strictEqual(result.get('bar'), 1); + strictEqual(result.get('qux'), 2); + }) .then(function () { obj._clearServerData(); const query = new Parse.Query(TestObject); @@ -3230,6 +3243,19 @@ describe('Parse.Query testing', () => { strictEqual(result.get('bar'), 1); strictEqual(result.get('qux'), undefined, "expected 'qux' field to be unset"); }) + .then(function () { + obj._clearServerData(); + const query = new Parse.Query(TestObject); + query.select('foo', 'bar', 'qux'); + return query.first(); + }) + .then(function (result) { + ok(result.id, 'expected object id to be set'); + ok(!result.dirty(), 'expected result not to be dirty'); + strictEqual(result.get('foo'), 'baz'); + strictEqual(result.get('bar'), 1); + strictEqual(result.get('qux'), 2); + }) .then( function () { done(); @@ -3241,7 +3267,7 @@ describe('Parse.Query testing', () => { ); }); - it('select keys', async () => { + it('select keys (arrays)', async () => { const obj = new TestObject({ foo: 'baz', bar: 1, hello: 'world' }); await obj.save(); @@ -3272,22 +3298,19 @@ describe('Parse.Query testing', () => { const response3 = await request({ url: Parse.serverURL + '/classes/TestObject', qs: { - keys: [''], + keys: ['foo', 'bar', 'hello'], where: JSON.stringify({ objectId: obj.id }), }, headers: masterKeyHeaders, }); - ok(response3.data.results[0].objectId, 'expected objectId to be set'); - ok(response3.data.results[0].createdAt, 'expected object createdAt to be set'); - ok(response3.data.results[0].updatedAt, 'expected object updatedAt to be set'); - expect(response3.data.results[0].foo).toBeUndefined(); - expect(response3.data.results[0].bar).toBeUndefined(); - expect(response3.data.results[0].hello).toBeUndefined(); + expect(response3.data.results[0].foo).toBe('baz'); + expect(response3.data.results[0].bar).toBe(1); + expect(response3.data.results[0].hello).toBe('world'); const response4 = await request({ url: Parse.serverURL + '/classes/TestObject', qs: { - keys: [], + keys: [''], where: JSON.stringify({ objectId: obj.id }), }, headers: masterKeyHeaders, @@ -3295,14 +3318,14 @@ describe('Parse.Query testing', () => { ok(response4.data.results[0].objectId, 'expected objectId to be set'); ok(response4.data.results[0].createdAt, 'expected object createdAt to be set'); ok(response4.data.results[0].updatedAt, 'expected object updatedAt to be set'); - expect(response4.data.results[0].foo).toBe('baz'); - expect(response4.data.results[0].bar).toBe(1); - expect(response4.data.results[0].hello).toBe('world'); + expect(response4.data.results[0].foo).toBeUndefined(); + expect(response4.data.results[0].bar).toBeUndefined(); + expect(response4.data.results[0].hello).toBeUndefined(); const response5 = await request({ url: Parse.serverURL + '/classes/TestObject', qs: { - keys: '', + keys: [], where: JSON.stringify({ objectId: obj.id }), }, headers: masterKeyHeaders, @@ -3310,11 +3333,31 @@ describe('Parse.Query testing', () => { ok(response5.data.results[0].objectId, 'expected objectId to be set'); ok(response5.data.results[0].createdAt, 'expected object createdAt to be set'); ok(response5.data.results[0].updatedAt, 'expected object updatedAt to be set'); - expect(response5.data.results[0].foo).toBeUndefined(); - expect(response5.data.results[0].bar).toBeUndefined(); - expect(response5.data.results[0].hello).toBeUndefined(); + expect(response5.data.results[0].foo).toBe('baz'); + expect(response5.data.results[0].bar).toBe(1); + expect(response5.data.results[0].hello).toBe('world'); + }); + + it('select keys (strings)', async () => { + const obj = new TestObject({ foo: 'baz', bar: 1, hello: 'world' }); + await obj.save(); - const response6 = await request({ + const response = await request({ + url: Parse.serverURL + '/classes/TestObject', + qs: { + keys: '', + where: JSON.stringify({ objectId: obj.id }), + }, + headers: masterKeyHeaders, + }); + ok(response.data.results[0].objectId, 'expected objectId to be set'); + ok(response.data.results[0].createdAt, 'expected object createdAt to be set'); + ok(response.data.results[0].updatedAt, 'expected object updatedAt to be set'); + expect(response.data.results[0].foo).toBeUndefined(); + expect(response.data.results[0].bar).toBeUndefined(); + expect(response.data.results[0].hello).toBeUndefined(); + + const response2 = await request({ url: Parse.serverURL + '/classes/TestObject', qs: { keys: '["foo", "hello"]', @@ -3322,12 +3365,27 @@ describe('Parse.Query testing', () => { }, headers: masterKeyHeaders, }); - ok(response6.data.results[0].objectId, 'expected objectId to be set'); - ok(response6.data.results[0].createdAt, 'expected object createdAt to be set'); - ok(response6.data.results[0].updatedAt, 'expected object updatedAt to be set'); - expect(response6.data.results[0].foo).toBe('baz'); - expect(response6.data.results[0].bar).toBeUndefined(); - expect(response6.data.results[0].hello).toBe('world'); + ok(response2.data.results[0].objectId, 'expected objectId to be set'); + ok(response2.data.results[0].createdAt, 'expected object createdAt to be set'); + ok(response2.data.results[0].updatedAt, 'expected object updatedAt to be set'); + expect(response2.data.results[0].foo).toBe('baz'); + expect(response2.data.results[0].bar).toBeUndefined(); + expect(response2.data.results[0].hello).toBe('world'); + + const response3 = await request({ + url: Parse.serverURL + '/classes/TestObject', + qs: { + keys: '["foo", "bar", "hello"]', + where: JSON.stringify({ objectId: obj.id }), + }, + headers: masterKeyHeaders, + }); + ok(response3.data.results[0].objectId, 'expected objectId to be set'); + ok(response3.data.results[0].createdAt, 'expected object createdAt to be set'); + ok(response3.data.results[0].updatedAt, 'expected object updatedAt to be set'); + expect(response3.data.results[0].foo).toBe('baz'); + expect(response3.data.results[0].bar).toBe(1); + expect(response3.data.results[0].hello).toBe('world'); }); it('exclude keys query JS SDK', function (done) { @@ -3414,6 +3472,32 @@ describe('Parse.Query testing', () => { strictEqual(result.get('bar'), undefined, "expected 'bar' field to be unset"); strictEqual(result.get('qux'), 2); }) + .then(function () { + obj._clearServerData(); + const query = new Parse.Query(TestObject); + query.exclude(['foo', 'bar', 'qux']); + return query.first(); + }) + .then(function (result) { + ok(result.id, 'expected object id to be set'); + ok(!result.dirty(), 'expected result not to be dirty'); + strictEqual(result.get('foo'), undefined, "expected 'bar' field to be unset"); + strictEqual(result.get('bar'), undefined, "expected 'bar' field to be unset"); + strictEqual(result.get('qux'), undefined, "expected 'bar' field to be unset"); + }) + .then(function () { + obj._clearServerData(); + const query = new Parse.Query(TestObject); + query.exclude('foo'); + return query.first(); + }) + .then(function (result) { + ok(result.id, 'expected object id to be set'); + ok(!result.dirty(), 'expected result not to be dirty'); + strictEqual(result.get('foo'), undefined, "expected 'bar' field to be unset"); + strictEqual(result.get('bar'), 1); + strictEqual(result.get('qux'), 2); + }) .then(function () { obj._clearServerData(); const query = new Parse.Query(TestObject); @@ -3427,6 +3511,19 @@ describe('Parse.Query testing', () => { strictEqual(result.get('bar'), undefined, "expected 'bar' field to be unset"); strictEqual(result.get('qux'), 2); }) + .then(function () { + obj._clearServerData(); + const query = new Parse.Query(TestObject); + query.exclude('foo', 'bar', 'qux'); + return query.first(); + }) + .then(function (result) { + ok(result.id, 'expected object id to be set'); + ok(!result.dirty(), 'expected result not to be dirty'); + strictEqual(result.get('foo'), undefined, "expected 'bar' field to be unset"); + strictEqual(result.get('bar'), undefined, "expected 'bar' field to be unset"); + strictEqual(result.get('qux'), undefined, "expected 'bar' field to be unset"); + }) .then( function () { done(); @@ -3438,14 +3535,14 @@ describe('Parse.Query testing', () => { ); }); - it('exclude keys', async () => { + it('exclude keys (arrays)', async () => { const obj = new TestObject({ foo: 'baz', hello: 'world' }); await obj.save(); const response = await request({ url: Parse.serverURL + '/classes/TestObject', qs: { - excludeKeys: 'foo', + excludeKeys: ['foo'], where: JSON.stringify({ objectId: obj.id }), }, headers: masterKeyHeaders, @@ -3497,8 +3594,27 @@ describe('Parse.Query testing', () => { ok(response4.data.results[0].updatedAt, 'expected object updatedAt to be set'); expect(response4.data.results[0].foo).toBe('baz'); expect(response4.data.results[0].hello).toBe('world'); + }); - const response5 = await request({ + it('exclude keys (strings)', async () => { + const obj = new TestObject({ foo: 'baz', hello: 'world' }); + await obj.save(); + + const response = await request({ + url: Parse.serverURL + '/classes/TestObject', + qs: { + excludeKeys: 'foo', + where: JSON.stringify({ objectId: obj.id }), + }, + headers: masterKeyHeaders, + }); + ok(response.data.results[0].objectId, 'expected objectId to be set'); + ok(response.data.results[0].createdAt, 'expected object createdAt to be set'); + ok(response.data.results[0].updatedAt, 'expected object updatedAt to be set'); + expect(response.data.results[0].foo).toBeUndefined(); + expect(response.data.results[0].hello).toBe('world'); + + const response2 = await request({ url: Parse.serverURL + '/classes/TestObject', qs: { excludeKeys: '', @@ -3506,13 +3622,13 @@ describe('Parse.Query testing', () => { }, headers: masterKeyHeaders, }); - ok(response5.data.results[0].objectId, 'expected objectId to be set'); - ok(response5.data.results[0].createdAt, 'expected object createdAt to be set'); - ok(response5.data.results[0].updatedAt, 'expected object updatedAt to be set'); - expect(response5.data.results[0].foo).toBe('baz'); - expect(response5.data.results[0].hello).toBe('world'); + ok(response2.data.results[0].objectId, 'expected objectId to be set'); + ok(response2.data.results[0].createdAt, 'expected object createdAt to be set'); + ok(response2.data.results[0].updatedAt, 'expected object updatedAt to be set'); + expect(response2.data.results[0].foo).toBe('baz'); + expect(response2.data.results[0].hello).toBe('world'); - const response6 = await request({ + const response3 = await request({ url: Parse.serverURL + '/classes/TestObject', qs: { excludeKeys: '["hello"]', @@ -3520,13 +3636,13 @@ describe('Parse.Query testing', () => { }, headers: masterKeyHeaders, }); - ok(response6.data.results[0].objectId, 'expected objectId to be set'); - ok(response6.data.results[0].createdAt, 'expected object createdAt to be set'); - ok(response6.data.results[0].updatedAt, 'expected object updatedAt to be set'); - expect(response6.data.results[0].foo).toBe('baz'); - expect(response6.data.results[0].hello).toBeUndefined(); + ok(response3.data.results[0].objectId, 'expected objectId to be set'); + ok(response3.data.results[0].createdAt, 'expected object createdAt to be set'); + ok(response3.data.results[0].updatedAt, 'expected object updatedAt to be set'); + expect(response3.data.results[0].foo).toBe('baz'); + expect(response3.data.results[0].hello).toBeUndefined(); - const response7 = await request({ + const response4 = await request({ url: Parse.serverURL + '/classes/TestObject', qs: { excludeKeys: '["foo", "hello"]', @@ -3534,11 +3650,11 @@ describe('Parse.Query testing', () => { }, headers: masterKeyHeaders, }); - ok(response7.data.results[0].objectId, 'expected objectId to be set'); - ok(response7.data.results[0].createdAt, 'expected object createdAt to be set'); - ok(response7.data.results[0].updatedAt, 'expected object updatedAt to be set'); - expect(response7.data.results[0].foo).toBeUndefined(); - expect(response7.data.results[0].hello).toBeUndefined(); + ok(response4.data.results[0].objectId, 'expected objectId to be set'); + ok(response4.data.results[0].createdAt, 'expected object createdAt to be set'); + ok(response4.data.results[0].updatedAt, 'expected object updatedAt to be set'); + expect(response4.data.results[0].foo).toBeUndefined(); + expect(response4.data.results[0].hello).toBeUndefined(); }); it('exclude keys with select same key', async () => { @@ -5154,19 +5270,6 @@ describe('Parse.Query testing', () => { equal(results[0].get('array').length, 105); }); - it('exclude keys (sdk query)', async done => { - const obj = new TestObject({ foo: 'baz', hello: 'world' }); - await obj.save(); - - const query = new Parse.Query('TestObject'); - query.exclude('foo'); - - const object = await query.get(obj.id); - expect(object.get('foo')).toBeUndefined(); - expect(object.get('hello')).toBe('world'); - done(); - }); - xit('todo: exclude keys with select key (sdk query get)', async done => { // there is some problem with js sdk caching From d8f0bcec43a0d5f0af198e858f3acc7eac363d02 Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Tue, 1 Jun 2021 10:18:37 -0400 Subject: [PATCH 21/23] use await for added tests --- spec/ParseQuery.spec.js | 575 +++++++++++++++++----------------------- 1 file changed, 245 insertions(+), 330 deletions(-) diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index a858d12e66..a56af0b437 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -3133,138 +3133,101 @@ describe('Parse.Query testing', () => { ); }); - it('select keys query JS SDK', function (done) { + it('select keys query JS SDK', async () => { const obj = new TestObject({ foo: 'baz', bar: 1, qux: 2 }); - - obj - .save() - .then(function () { - obj._clearServerData(); - const query = new Parse.Query(TestObject); - query.select('foo'); - return query.first(); - }) - .then(function (result) { - ok(result.id, 'expected object id to be set'); - ok(result.createdAt, 'expected object createdAt to be set'); - ok(result.updatedAt, 'expected object updatedAt to be set'); - ok(!result.dirty(), 'expected result not to be dirty'); - strictEqual(result.get('foo'), 'baz'); - strictEqual(result.get('bar'), undefined, "expected 'bar' field to be unset"); - strictEqual(result.get('qux'), undefined, "expected 'qux' field to be unset"); - return result.fetch(); - }) - .then(function (result) { - strictEqual(result.get('foo'), 'baz'); - strictEqual(result.get('bar'), 1); - strictEqual(result.get('qux'), 2); - }) - .then(function () { - obj._clearServerData(); - const query = new Parse.Query(TestObject); - query.select(); - return query.first(); - }) - .then(function (result) { - ok(result.id, 'expected object id to be set'); - ok(result.createdAt, 'expected object createdAt to be set'); - ok(result.updatedAt, 'expected object updatedAt to be set'); - ok(!result.dirty(), 'expected result not to be dirty'); - strictEqual(result.get('foo'), undefined, "expected 'foo' field to be unset"); - strictEqual(result.get('bar'), undefined, "expected 'bar' field to be unset"); - strictEqual(result.get('qux'), undefined, "expected 'qux' field to be unset"); - }) - .then(function () { - obj._clearServerData(); - const query = new Parse.Query(TestObject); - query.select([]); - return query.first(); - }) - .then(function (result) { - ok(result.id, 'expected object id to be set'); - ok(result.createdAt, 'expected object createdAt to be set'); - ok(result.updatedAt, 'expected object updatedAt to be set'); - ok(!result.dirty(), 'expected result not to be dirty'); - strictEqual(result.get('foo'), undefined, "expected 'foo' field to be unset"); - strictEqual(result.get('bar'), undefined, "expected 'bar' field to be unset"); - strictEqual(result.get('qux'), undefined, "expected 'qux' field to be unset"); - }) - .then(function () { - obj._clearServerData(); - const query = new Parse.Query(TestObject); - query.select(['foo']); - return query.first(); - }) - .then(function (result) { - ok(result.id, 'expected object id to be set'); - ok(result.createdAt, 'expected object createdAt to be set'); - ok(result.updatedAt, 'expected object updatedAt to be set'); - ok(!result.dirty(), 'expected result not to be dirty'); - strictEqual(result.get('foo'), 'baz'); - strictEqual(result.get('bar'), undefined, "expected 'bar' field to be unset"); - strictEqual(result.get('qux'), undefined, "expected 'qux' field to be unset"); - }) - .then(function () { - obj._clearServerData(); - const query = new Parse.Query(TestObject); - query.select(['foo', 'bar']); - return query.first(); - }) - .then(function (result) { - ok(result.id, 'expected object id to be set'); - ok(!result.dirty(), 'expected result not to be dirty'); - strictEqual(result.get('foo'), 'baz'); - strictEqual(result.get('bar'), 1); - strictEqual(result.get('qux'), undefined, "expected 'qux' field to be unset"); - }) - .then(function () { - obj._clearServerData(); - const query = new Parse.Query(TestObject); - query.select(['foo', 'bar', 'qux']); - return query.first(); - }) - .then(function (result) { - ok(result.id, 'expected object id to be set'); - ok(!result.dirty(), 'expected result not to be dirty'); - strictEqual(result.get('foo'), 'baz'); - strictEqual(result.get('bar'), 1); - strictEqual(result.get('qux'), 2); - }) - .then(function () { - obj._clearServerData(); - const query = new Parse.Query(TestObject); - query.select('foo', 'bar'); - return query.first(); - }) - .then(function (result) { - ok(result.id, 'expected object id to be set'); - ok(!result.dirty(), 'expected result not to be dirty'); - strictEqual(result.get('foo'), 'baz'); - strictEqual(result.get('bar'), 1); - strictEqual(result.get('qux'), undefined, "expected 'qux' field to be unset"); - }) - .then(function () { - obj._clearServerData(); - const query = new Parse.Query(TestObject); - query.select('foo', 'bar', 'qux'); - return query.first(); - }) - .then(function (result) { - ok(result.id, 'expected object id to be set'); - ok(!result.dirty(), 'expected result not to be dirty'); - strictEqual(result.get('foo'), 'baz'); - strictEqual(result.get('bar'), 1); - strictEqual(result.get('qux'), 2); - }) - .then( - function () { - done(); - }, - function (err) { - ok(false, 'other error: ' + JSON.stringify(err)); - done(); - } - ); + await obj.save(); + obj._clearServerData(); + var query1 = new Parse.Query(TestObject); + query1.select('foo'); + const result1 = await query1.first(); + ok(result1.id, 'expected object id to be set'); + ok(result1.createdAt, 'expected object createdAt to be set'); + ok(result1.updatedAt, 'expected object updatedAt to be set'); + ok(!result1.dirty(), 'expected result not to be dirty'); + strictEqual(result1.get('foo'), 'baz'); + strictEqual(result1.get('bar'), undefined, "expected 'bar' field to be unset"); + strictEqual(result1.get('qux'), undefined, "expected 'qux' field to be unset"); + + const result2 = await result1.fetch(); + strictEqual(result2.get('foo'), 'baz'); + strictEqual(result2.get('bar'), 1); + strictEqual(result2.get('qux'), 2); + + obj._clearServerData(); + var query2 = new Parse.Query(TestObject); + query2.select(); + const result3 = await query2.first(); + ok(result3.id, 'expected object id to be set'); + ok(result3.createdAt, 'expected object createdAt to be set'); + ok(result3.updatedAt, 'expected object updatedAt to be set'); + ok(!result3.dirty(), 'expected result not to be dirty'); + strictEqual(result3.get('foo'), undefined, "expected 'foo' field to be unset"); + strictEqual(result3.get('bar'), undefined, "expected 'bar' field to be unset"); + strictEqual(result3.get('qux'), undefined, "expected 'qux' field to be unset"); + + obj._clearServerData(); + var query3 = new Parse.Query(TestObject); + query3.select([]); + const result4 = await query3.first(); + ok(result4.id, 'expected object id to be set'); + ok(result4.createdAt, 'expected object createdAt to be set'); + ok(result4.updatedAt, 'expected object updatedAt to be set'); + ok(!result4.dirty(), 'expected result not to be dirty'); + strictEqual(result4.get('foo'), undefined, "expected 'foo' field to be unset"); + strictEqual(result4.get('bar'), undefined, "expected 'bar' field to be unset"); + strictEqual(result4.get('qux'), undefined, "expected 'qux' field to be unset"); + + obj._clearServerData(); + var query4 = new Parse.Query(TestObject); + query4.select(['foo']); + const result5 = await query4.first(); + ok(result5.id, 'expected object id to be set'); + ok(result5.createdAt, 'expected object createdAt to be set'); + ok(result5.updatedAt, 'expected object updatedAt to be set'); + ok(!result5.dirty(), 'expected result not to be dirty'); + strictEqual(result5.get('foo'), 'baz'); + strictEqual(result5.get('bar'), undefined, "expected 'bar' field to be unset"); + strictEqual(result5.get('qux'), undefined, "expected 'qux' field to be unset"); + + obj._clearServerData(); + var query5 = new Parse.Query(TestObject); + query5.select(['foo', 'bar']); + const result6 = await query5.first(); + ok(result6.id, 'expected object id to be set'); + ok(!result6.dirty(), 'expected result not to be dirty'); + strictEqual(result6.get('foo'), 'baz'); + strictEqual(result6.get('bar'), 1); + strictEqual(result6.get('qux'), undefined, "expected 'qux' field to be unset"); + + obj._clearServerData(); + var query6 = new Parse.Query(TestObject); + query6.select(['foo', 'bar', 'qux']); + const result7 = await query6.first(); + ok(result7.id, 'expected object id to be set'); + ok(!result7.dirty(), 'expected result not to be dirty'); + strictEqual(result7.get('foo'), 'baz'); + strictEqual(result7.get('bar'), 1); + strictEqual(result7.get('qux'), 2); + + obj._clearServerData(); + var query7 = new Parse.Query(TestObject); + query7.select('foo', 'bar'); + const result8 = await query7.first(); + ok(result8.id, 'expected object id to be set'); + ok(!result8.dirty(), 'expected result not to be dirty'); + strictEqual(result8.get('foo'), 'baz'); + strictEqual(result8.get('bar'), 1); + strictEqual(result8.get('qux'), undefined, "expected 'qux' field to be unset"); + + obj._clearServerData(); + var query8 = new Parse.Query(TestObject); + query8.select('foo', 'bar', 'qux'); + const result9 = await query8.first(); + ok(result9.id, 'expected object id to be set'); + ok(!result9.dirty(), 'expected result not to be dirty'); + strictEqual(result9.get('foo'), 'baz'); + strictEqual(result9.get('bar'), 1); + strictEqual(result9.get('qux'), 2); }); it('select keys (arrays)', async () => { @@ -3388,151 +3351,112 @@ describe('Parse.Query testing', () => { expect(response3.data.results[0].hello).toBe('world'); }); - it('exclude keys query JS SDK', function (done) { + it('exclude keys query JS SDK', async () => { const obj = new TestObject({ foo: 'baz', bar: 1, qux: 2 }); - obj - .save() - .then(function () { - obj._clearServerData(); - const query = new Parse.Query(TestObject); - query.exclude('foo'); - return query.first(); - }) - .then(function (result) { - ok(result.id, 'expected object id to be set'); - ok(result.createdAt, 'expected object createdAt to be set'); - ok(result.updatedAt, 'expected object updatedAt to be set'); - ok(!result.dirty(), 'expected result not to be dirty'); - strictEqual(result.get('foo'), undefined, "expected 'bar' field to be unset"); - strictEqual(result.get('bar'), 1); - strictEqual(result.get('qux'), 2); - return result.fetch(); - }) - .then(function (result) { - strictEqual(result.get('foo'), 'baz'); - strictEqual(result.get('bar'), 1); - strictEqual(result.get('qux'), 2); - }) - .then(function () { - obj._clearServerData(); - const query = new Parse.Query(TestObject); - query.exclude(); - return query.first(); - }) - .then(function (result) { - ok(result.id, 'expected object id to be set'); - ok(result.createdAt, 'expected object createdAt to be set'); - ok(result.updatedAt, 'expected object updatedAt to be set'); - ok(!result.dirty(), 'expected result not to be dirty'); - strictEqual(result.get('foo'), 'baz'); - strictEqual(result.get('bar'), 1); - strictEqual(result.get('qux'), 2); - }) - .then(function () { - obj._clearServerData(); - const query = new Parse.Query(TestObject); - query.exclude([]); - return query.first(); - }) - .then(function (result) { - ok(result.id, 'expected object id to be set'); - ok(result.createdAt, 'expected object createdAt to be set'); - ok(result.updatedAt, 'expected object updatedAt to be set'); - ok(!result.dirty(), 'expected result not to be dirty'); - strictEqual(result.get('foo'), 'baz'); - strictEqual(result.get('bar'), 1); - strictEqual(result.get('qux'), 2); - }) - .then(function () { - obj._clearServerData(); - const query = new Parse.Query(TestObject); - query.exclude(['foo']); - return query.first(); - }) - .then(function (result) { - ok(result.id, 'expected object id to be set'); - ok(result.createdAt, 'expected object createdAt to be set'); - ok(result.updatedAt, 'expected object updatedAt to be set'); - ok(!result.dirty(), 'expected result not to be dirty'); - strictEqual(result.get('foo'), undefined, "expected 'bar' field to be unset"); - strictEqual(result.get('bar'), 1); - strictEqual(result.get('qux'), 2); - }) - .then(function () { - obj._clearServerData(); - const query = new Parse.Query(TestObject); - query.exclude(['foo', 'bar']); - return query.first(); - }) - .then(function (result) { - ok(result.id, 'expected object id to be set'); - ok(!result.dirty(), 'expected result not to be dirty'); - strictEqual(result.get('foo'), undefined, "expected 'bar' field to be unset"); - strictEqual(result.get('bar'), undefined, "expected 'bar' field to be unset"); - strictEqual(result.get('qux'), 2); - }) - .then(function () { - obj._clearServerData(); - const query = new Parse.Query(TestObject); - query.exclude(['foo', 'bar', 'qux']); - return query.first(); - }) - .then(function (result) { - ok(result.id, 'expected object id to be set'); - ok(!result.dirty(), 'expected result not to be dirty'); - strictEqual(result.get('foo'), undefined, "expected 'bar' field to be unset"); - strictEqual(result.get('bar'), undefined, "expected 'bar' field to be unset"); - strictEqual(result.get('qux'), undefined, "expected 'bar' field to be unset"); - }) - .then(function () { - obj._clearServerData(); - const query = new Parse.Query(TestObject); - query.exclude('foo'); - return query.first(); - }) - .then(function (result) { - ok(result.id, 'expected object id to be set'); - ok(!result.dirty(), 'expected result not to be dirty'); - strictEqual(result.get('foo'), undefined, "expected 'bar' field to be unset"); - strictEqual(result.get('bar'), 1); - strictEqual(result.get('qux'), 2); - }) - .then(function () { - obj._clearServerData(); - const query = new Parse.Query(TestObject); - query.exclude('foo', 'bar'); - return query.first(); - }) - .then(function (result) { - ok(result.id, 'expected object id to be set'); - ok(!result.dirty(), 'expected result not to be dirty'); - strictEqual(result.get('foo'), undefined, "expected 'bar' field to be unset"); - strictEqual(result.get('bar'), undefined, "expected 'bar' field to be unset"); - strictEqual(result.get('qux'), 2); - }) - .then(function () { - obj._clearServerData(); - const query = new Parse.Query(TestObject); - query.exclude('foo', 'bar', 'qux'); - return query.first(); - }) - .then(function (result) { - ok(result.id, 'expected object id to be set'); - ok(!result.dirty(), 'expected result not to be dirty'); - strictEqual(result.get('foo'), undefined, "expected 'bar' field to be unset"); - strictEqual(result.get('bar'), undefined, "expected 'bar' field to be unset"); - strictEqual(result.get('qux'), undefined, "expected 'bar' field to be unset"); - }) - .then( - function () { - done(); - }, - function (err) { - ok(false, 'other error: ' + JSON.stringify(err)); - done(); - } - ); + await obj.save(); + obj._clearServerData(); + const query1 = new Parse.Query(TestObject); + query1.exclude('foo'); + const result1 = await query1.first(); + ok(result1.id, 'expected object id to be set'); + ok(result1.createdAt, 'expected object createdAt to be set'); + ok(result1.updatedAt, 'expected object updatedAt to be set'); + ok(!result1.dirty(), 'expected result not to be dirty'); + strictEqual(result1.get('foo'), undefined, "expected 'bar' field to be unset"); + strictEqual(result1.get('bar'), 1); + strictEqual(result1.get('qux'), 2); + + const result2 = await result1.fetch(); + strictEqual(result2.get('foo'), 'baz'); + strictEqual(result2.get('bar'), 1); + strictEqual(result2.get('qux'), 2); + + obj._clearServerData(); + const query2 = new Parse.Query(TestObject); + query2.exclude(); + const result3 = await query2.first(); + ok(result3.id, 'expected object id to be set'); + ok(result3.createdAt, 'expected object createdAt to be set'); + ok(result3.updatedAt, 'expected object updatedAt to be set'); + ok(!result3.dirty(), 'expected result not to be dirty'); + strictEqual(result3.get('foo'), 'baz'); + strictEqual(result3.get('bar'), 1); + strictEqual(result3.get('qux'), 2); + + obj._clearServerData(); + const query3 = new Parse.Query(TestObject); + query3.exclude([]); + const result4 = await query3.first(); + ok(result4.id, 'expected object id to be set'); + ok(result4.createdAt, 'expected object createdAt to be set'); + ok(result4.updatedAt, 'expected object updatedAt to be set'); + ok(!result4.dirty(), 'expected result not to be dirty'); + strictEqual(result4.get('foo'), 'baz'); + strictEqual(result4.get('bar'), 1); + strictEqual(result4.get('qux'), 2); + + obj._clearServerData(); + const query4 = new Parse.Query(TestObject); + query4.exclude(['foo']); + const result5 = await query4.first(); + ok(result5.id, 'expected object id to be set'); + ok(result5.createdAt, 'expected object createdAt to be set'); + ok(result5.updatedAt, 'expected object updatedAt to be set'); + ok(!result5.dirty(), 'expected result not to be dirty'); + strictEqual(result5.get('foo'), undefined, "expected 'bar' field to be unset"); + strictEqual(result5.get('bar'), 1); + strictEqual(result5.get('qux'), 2); + + obj._clearServerData(); + const query5 = new Parse.Query(TestObject); + query5.exclude(['foo', 'bar']); + const result6 = await query5.first(); + ok(result6.id, 'expected object id to be set'); + ok(!result6.dirty(), 'expected result not to be dirty'); + strictEqual(result6.get('foo'), undefined, "expected 'bar' field to be unset"); + strictEqual(result6.get('bar'), undefined, "expected 'bar' field to be unset"); + strictEqual(result6.get('qux'), 2); + + obj._clearServerData(); + const query6 = new Parse.Query(TestObject); + query6.exclude(['foo', 'bar', 'qux']); + const result7 = await query6.first(); + ok(result7.id, 'expected object id to be set'); + ok(!result7.dirty(), 'expected result not to be dirty'); + strictEqual(result7.get('foo'), undefined, "expected 'bar' field to be unset"); + strictEqual(result7.get('bar'), undefined, "expected 'bar' field to be unset"); + strictEqual(result7.get('qux'), undefined, "expected 'bar' field to be unset"); + + obj._clearServerData(); + const query7 = new Parse.Query(TestObject); + query7.exclude('foo'); + const result8 = await query7.first(); + ok(result8.id, 'expected object id to be set'); + ok(!result8.dirty(), 'expected result not to be dirty'); + strictEqual(result8.get('foo'), undefined, "expected 'bar' field to be unset"); + strictEqual(result8.get('bar'), 1); + strictEqual(result8.get('qux'), 2); + + obj._clearServerData(); + const query8 = new Parse.Query(TestObject); + query8.exclude('foo', 'bar'); + const result9 = await query8.first(); + ok(result9.id, 'expected object id to be set'); + ok(!result9.dirty(), 'expected result not to be dirty'); + strictEqual(result9.get('foo'), undefined, "expected 'bar' field to be unset"); + strictEqual(result9.get('bar'), undefined, "expected 'bar' field to be unset"); + strictEqual(result9.get('qux'), 2); + + obj._clearServerData(); + const query9 = new Parse.Query(TestObject); + query9.exclude('foo', 'bar', 'qux'); + const result10 = await query9.first(); + ok(result10.id, 'expected object id to be set'); + ok(!result10.dirty(), 'expected result not to be dirty'); + strictEqual(result10.get('foo'), undefined, "expected 'bar' field to be unset"); + strictEqual(result10.get('bar'), undefined, "expected 'bar' field to be unset"); + strictEqual(result10.get('qux'), undefined, "expected 'bar' field to be unset"); }); it('exclude keys (arrays)', async () => { @@ -4335,72 +4259,63 @@ describe('Parse.Query testing', () => { }); }); - it('exclude nested keys', function (done) { + it('exclude nested keys', async () => { const Foobar = new Parse.Object('Foobar'); const BarBaz = new Parse.Object('Barbaz'); BarBaz.set('key', 'value'); BarBaz.set('otherKey', 'value'); - BarBaz.save() - .then(() => { - Foobar.set('foo', 'bar'); - Foobar.set('fizz', 'buzz'); - Foobar.set('barBaz', BarBaz); - return Foobar.save(); - }) - .then(function (savedFoobar) { - const foobarQuery = new Parse.Query('Foobar'); - foobarQuery.exclude(['foo', 'barBaz.otherKey']); - foobarQuery.get(savedFoobar.id).then(function (foobarObj) { - equal(foobarObj.get('fizz'), 'buzz'); - equal(foobarObj.get('foo'), undefined); - if (foobarObj.has('barBaz')) { - equal(foobarObj.get('barBaz').get('key'), 'value'); - equal(foobarObj.get('barBaz').get('otherKey'), undefined); - } else { - fail('barBaz should be set'); - } - done(); - }); - }); - }); - - it('exclude nested keys 2 level', function (done) { + await BarBaz.save(); + + Foobar.set('foo', 'bar'); + Foobar.set('fizz', 'buzz'); + Foobar.set('barBaz', BarBaz); + const savedFoobar = await Foobar.save(); + + const foobarQuery = new Parse.Query('Foobar'); + foobarQuery.exclude(['foo', 'barBaz.otherKey']); + const foobarObj = await foobarQuery.get(savedFoobar.id); + equal(foobarObj.get('fizz'), 'buzz'); + equal(foobarObj.get('foo'), undefined); + if (foobarObj.has('barBaz')) { + equal(foobarObj.get('barBaz').get('key'), 'value'); + equal(foobarObj.get('barBaz').get('otherKey'), undefined); + } else { + fail('barBaz should be set'); + } + }); + + it('exclude nested keys 2 level', async () => { const Foobar = new Parse.Object('Foobar'); const BarBaz = new Parse.Object('Barbaz'); const Bazoo = new Parse.Object('Bazoo'); Bazoo.set('some', 'thing'); Bazoo.set('otherSome', 'value'); - Bazoo.save() - .then(() => { - BarBaz.set('key', 'value'); - BarBaz.set('otherKey', 'value'); - BarBaz.set('bazoo', Bazoo); - return BarBaz.save(); - }) - .then(() => { - Foobar.set('foo', 'bar'); - Foobar.set('fizz', 'buzz'); - Foobar.set('barBaz', BarBaz); - return Foobar.save(); - }) - .then(function (savedFoobar) { - const foobarQuery = new Parse.Query('Foobar'); - foobarQuery.exclude(['foo', 'barBaz.otherKey', 'barBaz.bazoo.otherSome']); - foobarQuery.get(savedFoobar.id).then(function (foobarObj) { - equal(foobarObj.get('fizz'), 'buzz'); - equal(foobarObj.get('foo'), undefined); - if (foobarObj.has('barBaz')) { - equal(foobarObj.get('barBaz').get('key'), 'value'); - equal(foobarObj.get('barBaz').get('otherKey'), undefined); - equal(foobarObj.get('barBaz').get('bazoo').get('some'), 'thing'); - equal(foobarObj.get('barBaz').get('bazoo').get('otherSome'), undefined); - } else { - fail('barBaz should be set'); - } - done(); - }); - }); + await Bazoo.save(); + + BarBaz.set('key', 'value'); + BarBaz.set('otherKey', 'value'); + BarBaz.set('bazoo', Bazoo); + await BarBaz.save(); + + Foobar.set('foo', 'bar'); + Foobar.set('fizz', 'buzz'); + Foobar.set('barBaz', BarBaz); + const savedFoobar = await Foobar.save(); + + const foobarQuery = new Parse.Query('Foobar'); + foobarQuery.exclude(['foo', 'barBaz.otherKey', 'barBaz.bazoo.otherSome']); + const foobarObj = await foobarQuery.get(savedFoobar.id); + equal(foobarObj.get('fizz'), 'buzz'); + equal(foobarObj.get('foo'), undefined); + if (foobarObj.has('barBaz')) { + equal(foobarObj.get('barBaz').get('key'), 'value'); + equal(foobarObj.get('barBaz').get('otherKey'), undefined); + equal(foobarObj.get('barBaz').get('bazoo').get('some'), 'thing'); + equal(foobarObj.get('barBaz').get('bazoo').get('otherSome'), undefined); + } else { + fail('barBaz should be set'); + } }); it('include with *', async () => { From 91b559294270aafd24d9ecbb97dd2fa8b44bf721 Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Tue, 1 Jun 2021 10:26:19 -0400 Subject: [PATCH 22/23] lint --- spec/ParseQuery.spec.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index a56af0b437..e196280a5c 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -3137,7 +3137,7 @@ describe('Parse.Query testing', () => { const obj = new TestObject({ foo: 'baz', bar: 1, qux: 2 }); await obj.save(); obj._clearServerData(); - var query1 = new Parse.Query(TestObject); + const query1 = new Parse.Query(TestObject); query1.select('foo'); const result1 = await query1.first(); ok(result1.id, 'expected object id to be set'); @@ -3154,7 +3154,7 @@ describe('Parse.Query testing', () => { strictEqual(result2.get('qux'), 2); obj._clearServerData(); - var query2 = new Parse.Query(TestObject); + const query2 = new Parse.Query(TestObject); query2.select(); const result3 = await query2.first(); ok(result3.id, 'expected object id to be set'); @@ -3166,7 +3166,7 @@ describe('Parse.Query testing', () => { strictEqual(result3.get('qux'), undefined, "expected 'qux' field to be unset"); obj._clearServerData(); - var query3 = new Parse.Query(TestObject); + const query3 = new Parse.Query(TestObject); query3.select([]); const result4 = await query3.first(); ok(result4.id, 'expected object id to be set'); @@ -3178,7 +3178,7 @@ describe('Parse.Query testing', () => { strictEqual(result4.get('qux'), undefined, "expected 'qux' field to be unset"); obj._clearServerData(); - var query4 = new Parse.Query(TestObject); + const query4 = new Parse.Query(TestObject); query4.select(['foo']); const result5 = await query4.first(); ok(result5.id, 'expected object id to be set'); @@ -3190,7 +3190,7 @@ describe('Parse.Query testing', () => { strictEqual(result5.get('qux'), undefined, "expected 'qux' field to be unset"); obj._clearServerData(); - var query5 = new Parse.Query(TestObject); + const query5 = new Parse.Query(TestObject); query5.select(['foo', 'bar']); const result6 = await query5.first(); ok(result6.id, 'expected object id to be set'); @@ -3198,9 +3198,9 @@ describe('Parse.Query testing', () => { strictEqual(result6.get('foo'), 'baz'); strictEqual(result6.get('bar'), 1); strictEqual(result6.get('qux'), undefined, "expected 'qux' field to be unset"); - + obj._clearServerData(); - var query6 = new Parse.Query(TestObject); + const query6 = new Parse.Query(TestObject); query6.select(['foo', 'bar', 'qux']); const result7 = await query6.first(); ok(result7.id, 'expected object id to be set'); @@ -3210,7 +3210,7 @@ describe('Parse.Query testing', () => { strictEqual(result7.get('qux'), 2); obj._clearServerData(); - var query7 = new Parse.Query(TestObject); + const query7 = new Parse.Query(TestObject); query7.select('foo', 'bar'); const result8 = await query7.first(); ok(result8.id, 'expected object id to be set'); @@ -3220,7 +3220,7 @@ describe('Parse.Query testing', () => { strictEqual(result8.get('qux'), undefined, "expected 'qux' field to be unset"); obj._clearServerData(); - var query8 = new Parse.Query(TestObject); + const query8 = new Parse.Query(TestObject); query8.select('foo', 'bar', 'qux'); const result9 = await query8.first(); ok(result9.id, 'expected object id to be set'); @@ -3366,7 +3366,7 @@ describe('Parse.Query testing', () => { strictEqual(result1.get('foo'), undefined, "expected 'bar' field to be unset"); strictEqual(result1.get('bar'), 1); strictEqual(result1.get('qux'), 2); - + const result2 = await result1.fetch(); strictEqual(result2.get('foo'), 'baz'); strictEqual(result2.get('bar'), 1); @@ -3407,7 +3407,7 @@ describe('Parse.Query testing', () => { strictEqual(result5.get('foo'), undefined, "expected 'bar' field to be unset"); strictEqual(result5.get('bar'), 1); strictEqual(result5.get('qux'), 2); - + obj._clearServerData(); const query5 = new Parse.Query(TestObject); query5.exclude(['foo', 'bar']); @@ -4265,12 +4265,12 @@ describe('Parse.Query testing', () => { BarBaz.set('key', 'value'); BarBaz.set('otherKey', 'value'); await BarBaz.save(); - + Foobar.set('foo', 'bar'); Foobar.set('fizz', 'buzz'); Foobar.set('barBaz', BarBaz); const savedFoobar = await Foobar.save(); - + const foobarQuery = new Parse.Query('Foobar'); foobarQuery.exclude(['foo', 'barBaz.otherKey']); const foobarObj = await foobarQuery.get(savedFoobar.id); @@ -4281,7 +4281,7 @@ describe('Parse.Query testing', () => { equal(foobarObj.get('barBaz').get('otherKey'), undefined); } else { fail('barBaz should be set'); - } + } }); it('exclude nested keys 2 level', async () => { @@ -4292,7 +4292,7 @@ describe('Parse.Query testing', () => { Bazoo.set('some', 'thing'); Bazoo.set('otherSome', 'value'); await Bazoo.save(); - + BarBaz.set('key', 'value'); BarBaz.set('otherKey', 'value'); BarBaz.set('bazoo', Bazoo); @@ -4315,7 +4315,7 @@ describe('Parse.Query testing', () => { equal(foobarObj.get('barBaz').get('bazoo').get('otherSome'), undefined); } else { fail('barBaz should be set'); - } + } }); it('include with *', async () => { From b06bf76de5d62d0b7f42ad398bf1e03f682850f7 Mon Sep 17 00:00:00 2001 From: Corey Date: Thu, 3 Jun 2021 15:13:25 -0400 Subject: [PATCH 23/23] Add suggestions --- src/RestQuery.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/RestQuery.js b/src/RestQuery.js index 3de17762fb..6039084e38 100644 --- a/src/RestQuery.js +++ b/src/RestQuery.js @@ -68,7 +68,7 @@ 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 = []; - var keysForInclude = []; + 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 @@ -76,6 +76,8 @@ function RestQuery( 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; }