From 70f6ec5792f1e7221c660b4ab26871b379b4c37b Mon Sep 17 00:00:00 2001 From: dblythy Date: Wed, 28 Dec 2022 12:29:24 +1100 Subject: [PATCH 01/20] feat: remove custom aggregate syntax --- spec/AggregateRouter.spec.js | 51 +++++----- spec/ParseQuery.Aggregate.spec.js | 161 ++++++++++++++---------------- src/Routers/AggregateRouter.js | 33 +++--- 3 files changed, 112 insertions(+), 133 deletions(-) diff --git a/spec/AggregateRouter.spec.js b/spec/AggregateRouter.spec.js index 4d038562bb..0f3800816b 100644 --- a/spec/AggregateRouter.spec.js +++ b/spec/AggregateRouter.spec.js @@ -1,11 +1,10 @@ const AggregateRouter = require('../lib/Routers/AggregateRouter').AggregateRouter; describe('AggregateRouter', () => { - // TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx) it('get pipeline from Array', () => { const body = [ { - group: { objectId: {} }, + $group: { _id: {} }, }, ]; const expected = [{ $group: { _id: {} } }]; @@ -13,22 +12,20 @@ describe('AggregateRouter', () => { expect(result).toEqual(expected); }); - // TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx) it('get pipeline from Object', () => { const body = { - group: { objectId: {} }, + $group: { _id: {} }, }; const expected = [{ $group: { _id: {} } }]; const result = AggregateRouter.getPipeline(body); expect(result).toEqual(expected); }); - // TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx) it('get pipeline from Pipeline Operator (Array)', () => { const body = { pipeline: [ { - group: { objectId: {} }, + $group: { _id: {} }, }, ], }; @@ -37,11 +34,10 @@ describe('AggregateRouter', () => { expect(result).toEqual(expected); }); - // TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx) it('get pipeline from Pipeline Operator (Object)', () => { const body = { pipeline: { - group: { objectId: {} }, + $group: { _id: {} }, }, }; const expected = [{ $group: { _id: {} } }]; @@ -49,43 +45,42 @@ describe('AggregateRouter', () => { expect(result).toEqual(expected); }); - // TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx) it('get pipeline fails multiple keys in Array stage ', () => { const body = [ { - group: { objectId: {} }, - match: { name: 'Test' }, + $group: { _id: {} }, + $match: { name: 'Test' }, }, ]; - try { - AggregateRouter.getPipeline(body); - } catch (e) { - expect(e.message).toBe('Pipeline stages should only have one key found group, match'); - } + expect(() => AggregateRouter.getPipeline(body)).toThrow( + new Parse.Error( + Parse.Error.INVALID_QUERY, + 'Pipeline stages should only have one key. Found $group, $match' + ) + ); }); - // TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx) it('get pipeline fails multiple keys in Pipeline Operator Array stage ', () => { const body = { pipeline: [ { - group: { objectId: {} }, - match: { name: 'Test' }, + $group: { _id: {} }, + $match: { name: 'Test' }, }, ], }; - try { - AggregateRouter.getPipeline(body); - } catch (e) { - expect(e.message).toBe('Pipeline stages should only have one key found group, match'); - } + expect(() => AggregateRouter.getPipeline(body)).toThrow( + new Parse.Error( + Parse.Error.INVALID_QUERY, + 'Pipeline stages should only have one key. Found $group, $match' + ) + ); }); - // TODO: update pipeline syntax. See [#7339](https://bit.ly/3incnWx) it('get search pipeline from Pipeline Operator (Array)', () => { const body = { pipeline: { - search: {}, + $search: {}, }, }; const expected = [{ $search: {} }]; @@ -145,10 +140,10 @@ describe('AggregateRouter', () => { it('support the use of `_id` in stages', () => { const body = [ - { match: { _id: 'randomId' } }, + { $match: { _id: 'randomId' } }, { sort: { _id: -1 } }, { addFields: { _id: 1 } }, - { group: { _id: {} } }, + { $group: { _id: {} } }, { project: { _id: 0 } }, ]; const expected = [ diff --git a/spec/ParseQuery.Aggregate.spec.js b/spec/ParseQuery.Aggregate.spec.js index 5bfe22683f..63b3f81ecb 100644 --- a/spec/ParseQuery.Aggregate.spec.js +++ b/spec/ParseQuery.Aggregate.spec.js @@ -23,28 +23,28 @@ const loadTestData = () => { const data1 = { score: 10, name: 'foo', - sender: { group: 'A' }, // TODO: change to `$group`. See [#7339](https://bit.ly/3incnWx) + sender: { group: 'A' }, views: 900, size: ['S', 'M'], }; const data2 = { score: 10, name: 'foo', - sender: { group: 'A' }, // TODO: change to `$group`. See [#7339](https://bit.ly/3incnWx) + sender: { group: 'A' }, views: 800, size: ['M', 'L'], }; const data3 = { score: 10, name: 'bar', - sender: { group: 'B' }, // TODO: change to `$group`. See [#7339](https://bit.ly/3incnWx) + sender: { group: 'B' }, views: 700, size: ['S'], }; const data4 = { score: 20, name: 'dpl', - sender: { group: 'B' }, // TODO: change to `$group`. See [#7339](https://bit.ly/3incnWx) + sender: { group: 'B' }, views: 700, size: ['S'], }; @@ -68,7 +68,7 @@ const get = function (url, options) { }); }; -describe('Parse.Query Aggregate testing', () => { +fdescribe('Parse.Query Aggregate testing', () => { beforeEach(done => { loadTestData().then(done, done); }); @@ -86,7 +86,7 @@ describe('Parse.Query Aggregate testing', () => { it('invalid query group _id required', done => { const options = Object.assign({}, masterKeyOptions, { body: { - group: {}, // TODO: write as `$group`. See [#7339](https://bit.ly/3incnWx) + $group: {}, }, }); get(Parse.serverURL + '/aggregate/TestObject', options).catch(error => { @@ -98,7 +98,7 @@ describe('Parse.Query Aggregate testing', () => { it('group by field', done => { const options = Object.assign({}, masterKeyOptions, { body: { - group: { objectId: '$name' }, // TODO: write as `$group`. See [#7339](https://bit.ly/3incnWx) + $group: { _id: '$name' }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -119,7 +119,7 @@ describe('Parse.Query Aggregate testing', () => { const options = Object.assign({}, masterKeyOptions, { body: { pipeline: { - group: { objectId: '$name' }, // TODO: write as `$group`. See [#7339](https://bit.ly/3incnWx) + $group: { _id: '$name' }, }, }, }); @@ -137,7 +137,7 @@ describe('Parse.Query Aggregate testing', () => { const obj = new TestObject(); const pipeline = [ { - group: { objectId: {} }, // TODO: write as `$group`. See [#7339](https://bit.ly/3incnWx) + $group: { _id: {} }, }, ]; obj @@ -156,7 +156,7 @@ describe('Parse.Query Aggregate testing', () => { const obj = new TestObject(); const pipeline = [ { - group: { objectId: '' }, // TODO: write as `$group`. See [#7339](https://bit.ly/3incnWx) + $group: { _id: '' }, }, ]; obj @@ -175,7 +175,7 @@ describe('Parse.Query Aggregate testing', () => { const obj = new TestObject(); const pipeline = [ { - group: { objectId: [] }, // TODO: write as `$group`. See [#7339](https://bit.ly/3incnWx) + $group: { _id: [] }, }, ]; obj @@ -196,9 +196,8 @@ describe('Parse.Query Aggregate testing', () => { const obj3 = new TestObject(); const pipeline = [ { - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { - objectId: { + $group: { + _id: { score: '$score', views: '$views', }, @@ -280,7 +279,7 @@ describe('Parse.Query Aggregate testing', () => { it('group by number', done => { const options = Object.assign({}, masterKeyOptions, { body: { - group: { objectId: '$score' }, // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) + $group: { _id: '$score' }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -302,9 +301,8 @@ describe('Parse.Query Aggregate testing', () => { const obj2 = new TestObject({ name: 'item b', quantity: 5, price: 5 }); const pipeline = [ { - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { - objectId: null, + $group: { + _id: null, total: { $sum: { $multiply: ['$quantity', '$price'] } }, }, }, @@ -326,10 +324,10 @@ describe('Parse.Query Aggregate testing', () => { const obj2 = new TestObject({ name: 'item b', quantity: 5, price: 5 }); const pipeline = [ { - match: { quantity: { $exists: true } }, + $match: { quantity: { $exists: true } }, }, { - project: { + $project: { name: 1, total: { $multiply: ['$quantity', '$price'] }, }, @@ -358,16 +356,16 @@ describe('Parse.Query Aggregate testing', () => { const obj2 = new TestObject({ name: 'item b', quantity: 5, price: 5 }); const pipeline = [ { - match: { quantity: { $exists: true } }, + $match: { quantity: { $exists: true } }, }, { - project: { - objectId: 0, // TODO: change to `_id`. See [#7339](https://bit.ly/3incnWx) + $project: { + _id: 0, total: { $multiply: ['$quantity', '$price'] }, }, }, { - sort: { total: 1 }, + $sort: { total: 1 }, }, ]; Parse.Object.saveAll([obj1, obj2]) @@ -388,7 +386,7 @@ describe('Parse.Query Aggregate testing', () => { it_exclude_dbs(['postgres'])('project updatedAt only transform', done => { const pipeline = [ { - project: { objectId: 0, updatedAt: 1 }, + $project: { _id: 0, updatedAt: 1 }, }, ]; const query = new Parse.Query(TestObject); @@ -411,13 +409,13 @@ describe('Parse.Query Aggregate testing', () => { const obj3 = new TestObject({ dateField2019: new Date(1990, 11, 1) }); const pipeline = [ { - match: { + $match: { dateField2019: { $exists: true }, }, }, { - group: { - objectId: { + $group: { + _id: { day: { $dayOfMonth: '$dateField2019' }, month: { $month: '$dateField2019' }, year: { $year: '$dateField2019' }, @@ -449,9 +447,8 @@ describe('Parse.Query Aggregate testing', () => { const obj3 = new TestObject({ dateField2019: new Date(1990, 11, 1) }); const pipeline = [ { - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { - objectId: { + $group: { + _id: { day: { $dayOfMonth: '$dateField2019' }, month: { $month: '$dateField2019' }, year: { $year: '$dateField2019' }, @@ -481,7 +478,7 @@ describe('Parse.Query Aggregate testing', () => { const obj1 = new TestObject({ pointer: pointer1 }); const obj2 = new TestObject({ pointer: pointer2 }); const obj3 = new TestObject({ pointer: pointer1 }); - const pipeline = [{ group: { objectId: '$pointer' } }]; + const pipeline = [{ $group: { _id: '$pointer' } }]; Parse.Object.saveAll([pointer1, pointer2, obj1, obj2, obj3]) .then(() => { const query = new Parse.Query(TestObject); @@ -499,8 +496,7 @@ describe('Parse.Query Aggregate testing', () => { it('group sum query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { objectId: null, total: { $sum: '$score' } }, + $group: { _id: null, total: { $sum: '$score' } }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -516,8 +512,7 @@ describe('Parse.Query Aggregate testing', () => { it('group count query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { objectId: null, total: { $sum: 1 } }, + $group: { _id: null, total: { $sum: 1 } }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -533,8 +528,7 @@ describe('Parse.Query Aggregate testing', () => { it('group min query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { objectId: null, minScore: { $min: '$score' } }, + $group: { _id: null, minScore: { $min: '$score' } }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -550,8 +544,7 @@ describe('Parse.Query Aggregate testing', () => { it('group max query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { objectId: null, maxScore: { $max: '$score' } }, + $group: { _id: null, maxScore: { $max: '$score' } }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -567,8 +560,7 @@ describe('Parse.Query Aggregate testing', () => { it('group avg query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { objectId: null, avgScore: { $avg: '$score' } }, + $group: { _id: null, avgScore: { $avg: '$score' } }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -584,7 +576,7 @@ describe('Parse.Query Aggregate testing', () => { it('limit query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - limit: 2, + $limit: 2, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -598,7 +590,7 @@ describe('Parse.Query Aggregate testing', () => { it('sort ascending query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - sort: { name: 1 }, + $sort: { name: 1 }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -616,7 +608,7 @@ describe('Parse.Query Aggregate testing', () => { it('sort decending query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - sort: { name: -1 }, + $sort: { name: -1 }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -634,7 +626,7 @@ describe('Parse.Query Aggregate testing', () => { it('skip query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - skip: 2, + $skip: 2, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -654,7 +646,7 @@ describe('Parse.Query Aggregate testing', () => { const obj1 = new TestObject({ dateField: yesterday }); const obj2 = new TestObject({ dateField: today }); const obj3 = new TestObject({ dateField: tomorrow }); - const pipeline = [{ match: { dateField: { $lt: tomorrow } } }]; + const pipeline = [{ $match: { dateField: { $lt: tomorrow } } }]; Parse.Object.saveAll([obj1, obj2, obj3]) .then(() => { const query = new Parse.Query(TestObject); @@ -686,7 +678,7 @@ describe('Parse.Query Aggregate testing', () => { it('match comparison query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - match: { score: { $gt: 15 } }, + $match: { score: { $gt: 15 } }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -701,7 +693,7 @@ describe('Parse.Query Aggregate testing', () => { it('match multiple comparison query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - match: { score: { $gt: 5, $lt: 15 } }, + $match: { score: { $gt: 5, $lt: 15 } }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -718,7 +710,7 @@ describe('Parse.Query Aggregate testing', () => { it('match complex comparison query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - match: { score: { $gt: 5, $lt: 15 }, views: { $gt: 850, $lt: 1000 } }, + $match: { score: { $gt: 5, $lt: 15 }, views: { $gt: 850, $lt: 1000 } }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -734,7 +726,7 @@ describe('Parse.Query Aggregate testing', () => { it('match comparison and equality query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - match: { score: { $gt: 5, $lt: 15 }, views: 900 }, + $match: { score: { $gt: 5, $lt: 15 }, views: 900 }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -750,7 +742,7 @@ describe('Parse.Query Aggregate testing', () => { it('match $or query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - match: { + $match: { $or: [{ score: { $gt: 15, $lt: 25 } }, { views: { $gt: 750, $lt: 850 } }], }, }, @@ -775,7 +767,7 @@ describe('Parse.Query Aggregate testing', () => { const obj2 = new TestObject(); Parse.Object.saveAll([obj1, obj2]) .then(() => { - const pipeline = [{ match: { objectId: obj1.id } }]; + const pipeline = [{ $match: { _id: obj1.id } }]; const query = new Parse.Query(TestObject); return query.aggregate(pipeline); }) @@ -791,7 +783,7 @@ describe('Parse.Query Aggregate testing', () => { const obj2 = new TestObject({ name: 'TestObject2' }); Parse.Object.saveAll([obj1, obj2]) .then(() => { - const pipeline = [{ match: { name: 'TestObject1' } }]; + const pipeline = [{ $match: { name: 'TestObject1' } }]; const query = new Parse.Query(TestObject); return query.aggregate(pipeline); }) @@ -811,7 +803,7 @@ describe('Parse.Query Aggregate testing', () => { Parse.Object.saveAll([pointer1, pointer2, obj1, obj2, obj3]) .then(() => { - const pipeline = [{ match: { pointer: pointer1.id } }]; + const pipeline = [{ $match: { pointer: pointer1.id } }]; const query = new Parse.Query(TestObject); return query.aggregate(pipeline); }) @@ -826,7 +818,7 @@ describe('Parse.Query Aggregate testing', () => { }); it_exclude_dbs(['postgres'])('match exists query', done => { - const pipeline = [{ match: { score: { $exists: true } } }]; + const pipeline = [{ $match: { score: { $exists: true } } }]; const query = new Parse.Query(TestObject); query.aggregate(pipeline).then(results => { expect(results.length).toEqual(4); @@ -842,7 +834,7 @@ describe('Parse.Query Aggregate testing', () => { .then(() => { const now = new Date(); const today = new Date(now.getFullYear(), now.getMonth(), now.getDate()); - const pipeline = [{ match: { createdAt: { $gte: today } } }]; + const pipeline = [{ $match: { createdAt: { $gte: today } } }]; const query = new Parse.Query(TestObject); return query.aggregate(pipeline); }) @@ -861,7 +853,7 @@ describe('Parse.Query Aggregate testing', () => { .then(() => { const now = new Date(); const today = new Date(now.getFullYear(), now.getMonth(), now.getDate()); - const pipeline = [{ match: { updatedAt: { $gte: today } } }]; + const pipeline = [{ $match: { updatedAt: { $gte: today } } }]; const query = new Parse.Query(TestObject); return query.aggregate(pipeline); }) @@ -880,7 +872,7 @@ describe('Parse.Query Aggregate testing', () => { .then(() => { const now = new Date(); const future = new Date(now.getFullYear(), now.getMonth() + 1, now.getDate()); - const pipeline = [{ match: { createdAt: future } }]; + const pipeline = [{ $match: { createdAt: future } }]; const query = new Parse.Query(TestObject); return query.aggregate(pipeline); }) @@ -899,7 +891,7 @@ describe('Parse.Query Aggregate testing', () => { Parse.Object.saveAll([pointer, obj1, obj2, obj3]) .then(() => { - const pipeline = [{ match: { pointer: { $exists: true } } }]; + const pipeline = [{ $match: { pointer: { $exists: true } } }]; const query = new Parse.Query(TestObject); return query.aggregate(pipeline); }) @@ -938,7 +930,7 @@ describe('Parse.Query Aggregate testing', () => { ( await new Parse.Query('MyCollection').aggregate([ { - match: { + $match: { language: { $in: [null, 'en'] }, }, }, @@ -952,7 +944,7 @@ describe('Parse.Query Aggregate testing', () => { ( await new Parse.Query('MyCollection').aggregate([ { - match: { + $match: { $or: [{ language: 'en' }, { language: null }], }, }, @@ -966,7 +958,7 @@ describe('Parse.Query Aggregate testing', () => { it('project query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - project: { name: 1 }, + $project: { name: 1 }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -986,7 +978,7 @@ describe('Parse.Query Aggregate testing', () => { it('multiple project query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - project: { name: 1, score: 1, sender: 1 }, + $project: { name: 1, score: 1, sender: 1 }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -1011,8 +1003,8 @@ describe('Parse.Query Aggregate testing', () => { .save() .then(() => { const pipeline = [ - { match: { objectId: obj.id } }, - { project: { pointer: 1, name: 1, createdAt: 1 } }, + { $match: { _id: obj.id } }, + { $project: { pointer: 1, name: 1, createdAt: 1 } }, ]; const query = new Parse.Query(TestObject); return query.aggregate(pipeline); @@ -1029,9 +1021,8 @@ describe('Parse.Query Aggregate testing', () => { it('project with group query', done => { const options = Object.assign({}, masterKeyOptions, { body: { - project: { score: 1 }, - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { objectId: '$score', score: { $sum: '$score' } }, + $project: { score: 1 }, + $group: { _id: '$score', score: { $sum: '$score' } }, }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -1058,8 +1049,7 @@ describe('Parse.Query Aggregate testing', () => { it('class does not exist return empty', done => { const options = Object.assign({}, masterKeyOptions, { body: { - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { objectId: null, total: { $sum: '$score' } }, + $group: { _id: null, total: { $sum: '$score' } }, }, }); get(Parse.serverURL + '/aggregate/UnknownClass', options) @@ -1073,8 +1063,7 @@ describe('Parse.Query Aggregate testing', () => { it('field does not exist return empty', done => { const options = Object.assign({}, masterKeyOptions, { body: { - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { objectId: null, total: { $sum: '$unknownfield' } }, + $group: { _id: null, total: { $sum: '$unknownfield' } }, }, }); get(Parse.serverURL + '/aggregate/UnknownClass', options) @@ -1085,7 +1074,7 @@ describe('Parse.Query Aggregate testing', () => { .catch(done.fail); }); - it('distinct query', done => { + fit('distinct query', done => { const options = Object.assign({}, masterKeyOptions, { body: { distinct: 'score' }, }); @@ -1103,7 +1092,7 @@ describe('Parse.Query Aggregate testing', () => { const options = Object.assign({}, masterKeyOptions, { body: { distinct: 'score', - where: { + $where: { name: 'bar', }, }, @@ -1120,7 +1109,7 @@ describe('Parse.Query Aggregate testing', () => { const options = Object.assign({}, masterKeyOptions, { body: { distinct: 'score', - where: JSON.stringify({ name: 'bar' }), + $where: JSON.stringify({ name: 'bar' }), }, }); get(Parse.serverURL + '/aggregate/TestObject', options) @@ -1270,7 +1259,7 @@ describe('Parse.Query Aggregate testing', () => { it('does not return sensitive hidden properties', done => { const options = Object.assign({}, masterKeyOptions, { body: { - match: { + $match: { score: { $gt: 5, }, @@ -1317,7 +1306,7 @@ describe('Parse.Query Aggregate testing', () => { }); it_exclude_dbs(['postgres'])('aggregate allow multiple of same stage', async done => { - await reconfigureServer(); + await reconfigureServer({ silent: false }); const pointer1 = new TestObject({ value: 1 }); const pointer2 = new TestObject({ value: 2 }); const pointer3 = new TestObject({ value: 3 }); @@ -1330,17 +1319,17 @@ describe('Parse.Query Aggregate testing', () => { body: { pipeline: [ { - match: { name: 'Hello' }, + $match: { name: 'Hello' }, }, { // Transform className$objectId to objectId and store in new field tempPointer - project: { + $project: { tempPointer: { $substr: ['$_p_pointer', 11, -1] }, // Remove TestObject$ }, }, { // Left Join, replace objectId stored in tempPointer with an actual object - lookup: { + $lookup: { from: 'test_TestObject', localField: 'tempPointer', foreignField: '_id', @@ -1349,12 +1338,12 @@ describe('Parse.Query Aggregate testing', () => { }, { // lookup returns an array, Deconstructs an array field to objects - unwind: { + $unwind: { path: '$tempPointer', }, }, { - match: { 'tempPointer.value': 2 }, + $match: { 'tempPointer.value': 2 }, }, ], }, @@ -1398,7 +1387,7 @@ describe('Parse.Query Aggregate testing', () => { // Create query const pipeline = [ { - geoNear: { + $geoNear: { near: { type: 'Point', coordinates: [1, 1], @@ -1451,7 +1440,7 @@ describe('Parse.Query Aggregate testing', () => { // Create query const pipeline = [ { - geoNear: { + $geoNear: { near: { type: 'Point', coordinates: [1, 1], @@ -1497,7 +1486,7 @@ describe('Parse.Query Aggregate testing', () => { // Create query const pipeline = [ { - geoNear: { + $geoNear: { near: [1, 1], key: 'location', spherical: true, diff --git a/src/Routers/AggregateRouter.js b/src/Routers/AggregateRouter.js index 7c587bedec..be7b297424 100644 --- a/src/Routers/AggregateRouter.js +++ b/src/Routers/AggregateRouter.js @@ -3,7 +3,6 @@ import rest from '../rest'; import * as middleware from '../middlewares'; import Parse from 'parse/node'; import UsersRouter from './UsersRouter'; -import Deprecator from '../Deprecator/Deprecator'; export class AggregateRouter extends ClassesRouter { handleFind(req) { @@ -83,22 +82,26 @@ export class AggregateRouter extends ClassesRouter { return pipeline.map(stage => { const keys = Object.keys(stage); - if (keys.length != 1) { - throw new Error(`Pipeline stages should only have one key found ${keys.join(', ')}`); + if (keys.length !== 1) { + throw new Parse.Error( + Parse.Error.INVALID_QUERY, + `Pipeline stages should only have one key. Found ${keys.join(', ')}` + ); } return AggregateRouter.transformStage(keys[0], stage); }); } static transformStage(stageName, stage) { - if (stageName === 'group') { + if (stageName[0] !== '$' && stageName !== 'distinct') { + throw new Parse.Error(Parse.Error.INVALID_QUERY, `Invalid aggregate stage: ${stageName}.`); + } + if (stageName === '$group') { if (Object.prototype.hasOwnProperty.call(stage[stageName], 'objectId')) { - Deprecator.logRuntimeDeprecation({ - usage: 'The use of objectId in aggregation stage $group', - solution: 'Use _id instead.', - }); - stage[stageName]._id = stage[stageName].objectId; - delete stage[stageName].objectId; + throw new Parse.Error( + Parse.Error.INVALID_QUERY, + `Cannot use objectId in aggregation stage $group.` + ); } if (!Object.prototype.hasOwnProperty.call(stage[stageName], '_id')) { throw new Parse.Error( @@ -107,15 +110,7 @@ export class AggregateRouter extends ClassesRouter { ); } } - - if (stageName[0] !== '$') { - Deprecator.logRuntimeDeprecation({ - usage: "Using aggregation stages without a leading '$'", - solution: `Try $${stageName} instead.`, - }); - } - const key = stageName[0] === '$' ? stageName : `$${stageName}`; - return { [key]: stage[stageName] }; + return { [stageName]: stage[stageName] }; } mountRoutes() { From 6ce5ad466216abc6cfe921b63f39ad3f66ad8e02 Mon Sep 17 00:00:00 2001 From: dblythy Date: Wed, 28 Dec 2022 12:32:31 +1100 Subject: [PATCH 02/20] Update ParseQuery.Aggregate.spec.js --- spec/ParseQuery.Aggregate.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/ParseQuery.Aggregate.spec.js b/spec/ParseQuery.Aggregate.spec.js index 63b3f81ecb..a61305286c 100644 --- a/spec/ParseQuery.Aggregate.spec.js +++ b/spec/ParseQuery.Aggregate.spec.js @@ -68,7 +68,7 @@ const get = function (url, options) { }); }; -fdescribe('Parse.Query Aggregate testing', () => { +describe('Parse.Query Aggregate testing', () => { beforeEach(done => { loadTestData().then(done, done); }); @@ -1074,7 +1074,7 @@ fdescribe('Parse.Query Aggregate testing', () => { .catch(done.fail); }); - fit('distinct query', done => { + it('distinct query', done => { const options = Object.assign({}, masterKeyOptions, { body: { distinct: 'score' }, }); From 7bdb327c474d73868575f458924d77b7e7be3fa6 Mon Sep 17 00:00:00 2001 From: dblythy Date: Wed, 28 Dec 2022 14:04:15 +1100 Subject: [PATCH 03/20] tests --- spec/AggregateRouter.spec.js | 8 ++++---- spec/ParseQuery.hint.spec.js | 16 ++++++++-------- spec/ReadPreferenceOption.spec.js | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/spec/AggregateRouter.spec.js b/spec/AggregateRouter.spec.js index 0f3800816b..6e3218e07d 100644 --- a/spec/AggregateRouter.spec.js +++ b/spec/AggregateRouter.spec.js @@ -100,7 +100,7 @@ describe('AggregateRouter', () => { it('support nested stage names starting with `$`', () => { const body = [ { - lookup: { + $lookup: { from: 'ACollection', let: { id: '_id' }, as: 'results', @@ -141,10 +141,10 @@ describe('AggregateRouter', () => { it('support the use of `_id` in stages', () => { const body = [ { $match: { _id: 'randomId' } }, - { sort: { _id: -1 } }, - { addFields: { _id: 1 } }, + { $sort: { _id: -1 } }, + { $addFields: { _id: 1 } }, { $group: { _id: {} } }, - { project: { _id: 0 } }, + { $project: { _id: 0 } }, ]; const expected = [ { $match: { _id: 'randomId' } }, diff --git a/spec/ParseQuery.hint.spec.js b/spec/ParseQuery.hint.spec.js index e5498bab96..c398aa0989 100644 --- a/spec/ParseQuery.hint.spec.js +++ b/spec/ParseQuery.hint.spec.js @@ -322,7 +322,7 @@ describe_only_db('mongo')('Parse.Query hint', () => { url: Parse.serverURL + '/aggregate/TestObject', qs: { explain: true, - group: JSON.stringify({ objectId: '$foo' }), + $group: JSON.stringify({ _id: '$foo' }), }, }); let response = await request(options); @@ -334,7 +334,7 @@ describe_only_db('mongo')('Parse.Query hint', () => { qs: { explain: true, hint: '_id_', - group: JSON.stringify({ objectId: '$foo' }), + $group: JSON.stringify({ _id: '$foo' }), }, }); response = await request(options); @@ -349,7 +349,7 @@ describe_only_db('mongo')('Parse.Query hint', () => { url: Parse.serverURL + '/aggregate/TestObject', qs: { explain: true, - group: JSON.stringify({ objectId: '$foo' }), + $group: JSON.stringify({ _id: '$foo' }), }, }); let response = await request(options); @@ -363,7 +363,7 @@ describe_only_db('mongo')('Parse.Query hint', () => { qs: { explain: true, hint: '_id_', - group: JSON.stringify({ objectId: '$foo' }), + $group: JSON.stringify({ _id: '$foo' }), }, }); response = await request(options); @@ -382,7 +382,7 @@ describe_only_db('mongo')('Parse.Query hint', () => { url: Parse.serverURL + '/aggregate/TestObject', qs: { explain: true, - group: JSON.stringify({ objectId: '$foo' }), + $group: JSON.stringify({ _id: '$foo' }), }, }); let response = await request(options); @@ -396,7 +396,7 @@ describe_only_db('mongo')('Parse.Query hint', () => { qs: { explain: true, hint: '_id_', - group: JSON.stringify({ objectId: '$foo' }), + $group: JSON.stringify({ _id: '$foo' }), }, }); response = await request(options); @@ -415,7 +415,7 @@ describe_only_db('mongo')('Parse.Query hint', () => { url: Parse.serverURL + '/aggregate/TestObject', qs: { explain: true, - group: JSON.stringify({ objectId: '$foo' }), + $group: JSON.stringify({ _id: '$foo' }), }, }); let response = await request(options); @@ -429,7 +429,7 @@ describe_only_db('mongo')('Parse.Query hint', () => { qs: { explain: true, hint: '_id_', - group: JSON.stringify({ objectId: '$foo' }), + $group: JSON.stringify({ _id: '$foo' }), }, }); response = await request(options); diff --git a/spec/ReadPreferenceOption.spec.js b/spec/ReadPreferenceOption.spec.js index 535c35c8b0..67b976674b 100644 --- a/spec/ReadPreferenceOption.spec.js +++ b/spec/ReadPreferenceOption.spec.js @@ -625,7 +625,7 @@ describe_only_db('mongo')('Read preference option', () => { spyOn(Collection.prototype, 'aggregate').and.callThrough(); // Query const query = new Parse.Query('MyObject'); - const results = await query.aggregate([{ match: { boolKey: false } }]); + const results = await query.aggregate([{ $match: { boolKey: false } }]); // Validate expect(results.length).toBe(1); let readPreference = null; @@ -678,7 +678,7 @@ describe_only_db('mongo')('Read preference option', () => { // Query const query = new Parse.Query('MyObject'); query.readPreference('SECONDARY'); - const results = await query.aggregate([{ match: { boolKey: false } }]); + const results = await query.aggregate([{ $match: { boolKey: false } }]); // Validate expect(results.length).toBe(1); let readPreference = null; From 49a2e6d512064112b9d168df81404c9b59ddfa34 Mon Sep 17 00:00:00 2001 From: dblythy Date: Wed, 28 Dec 2022 14:39:31 +1100 Subject: [PATCH 04/20] wip --- spec/CloudCode.spec.js | 2 +- src/Routers/AggregateRouter.js | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index 89bc3fdaa0..c02999ad51 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -2774,7 +2774,7 @@ describe('afterFind hooks', () => { const obj = new Parse.Object('MyObject'); const pipeline = [ { - group: { objectId: {} }, + $group: { _id: {} }, }, ]; obj diff --git a/src/Routers/AggregateRouter.js b/src/Routers/AggregateRouter.js index be7b297424..74d20f0bc7 100644 --- a/src/Routers/AggregateRouter.js +++ b/src/Routers/AggregateRouter.js @@ -93,7 +93,11 @@ export class AggregateRouter extends ClassesRouter { } static transformStage(stageName, stage) { - if (stageName[0] !== '$' && stageName !== 'distinct') { + const skipKeys = ['distinct', 'where']; + if (skipKeys.includes(stageName)) { + return; + } + if (stageName[0] !== '$') { throw new Parse.Error(Parse.Error.INVALID_QUERY, `Invalid aggregate stage: ${stageName}.`); } if (stageName === '$group') { From 1a1eca1504281a2f64b5199ef7dd7f8e82b92563 Mon Sep 17 00:00:00 2001 From: dblythy Date: Wed, 28 Dec 2022 14:59:20 +1100 Subject: [PATCH 05/20] Update PostgresStorageAdapter.js --- src/Adapters/Storage/Postgres/PostgresStorageAdapter.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js index 8e9858254d..444e4e8cca 100644 --- a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js +++ b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js @@ -2241,8 +2241,11 @@ export class PostgresStorageAdapter implements StorageAdapter { }); stage.$match = collapse; } - for (const field in stage.$match) { + for (let field in stage.$match) { const value = stage.$match[field]; + if (field === '_id') { + field = 'objectId'; + } const matchPatterns = []; Object.keys(ParseToPosgresComparator).forEach(cmp => { if (value[cmp]) { From 7b964897ec21163c11108fa4feb1b8b5f94c075c Mon Sep 17 00:00:00 2001 From: dblythy Date: Wed, 28 Dec 2022 15:47:35 +1100 Subject: [PATCH 06/20] Update AggregateRouter.spec.js --- spec/AggregateRouter.spec.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/spec/AggregateRouter.spec.js b/spec/AggregateRouter.spec.js index 6e3218e07d..20c0d66a74 100644 --- a/spec/AggregateRouter.spec.js +++ b/spec/AggregateRouter.spec.js @@ -156,4 +156,16 @@ describe('AggregateRouter', () => { const result = AggregateRouter.getPipeline(body); expect(result).toEqual(expected); }); + + it('should throw with invalid stage', () => { + expect(() => AggregateRouter.getPipeline([{ foo: 'bar' }])).toThrow( + new Parse.Error(Parse.Error.INVALID_QUERY, `Invalid aggregate stage: foo.`) + ); + }); + + it('should throw with invalid group', () => { + expect(() => AggregateRouter.getPipeline([{ $group: { objectId: 'bar' } }])).toThrow( + new Parse.Error(Parse.Error.INVALID_QUERY, `Cannot use objectId in aggregation stage $group.`) + ); + }); }); From 83cdf345046ec7310a5ff254efa8c949660214c0 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 29 Dec 2022 14:07:38 +1100 Subject: [PATCH 07/20] Update spec/AggregateRouter.spec.js Co-authored-by: Manuel <5673677+mtrezza@users.noreply.github.com> --- spec/AggregateRouter.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/AggregateRouter.spec.js b/spec/AggregateRouter.spec.js index 20c0d66a74..38df2f2884 100644 --- a/spec/AggregateRouter.spec.js +++ b/spec/AggregateRouter.spec.js @@ -55,7 +55,7 @@ describe('AggregateRouter', () => { expect(() => AggregateRouter.getPipeline(body)).toThrow( new Parse.Error( Parse.Error.INVALID_QUERY, - 'Pipeline stages should only have one key. Found $group, $match' + 'Pipeline stages should only have one key but found $group, $match.' ) ); }); From 0436ebe14540ea2e84dcaf7dd73051cd1b827794 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 29 Dec 2022 14:07:47 +1100 Subject: [PATCH 08/20] Update spec/AggregateRouter.spec.js Co-authored-by: Manuel <5673677+mtrezza@users.noreply.github.com> --- spec/AggregateRouter.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/AggregateRouter.spec.js b/spec/AggregateRouter.spec.js index 38df2f2884..18f9345b4b 100644 --- a/spec/AggregateRouter.spec.js +++ b/spec/AggregateRouter.spec.js @@ -165,7 +165,7 @@ describe('AggregateRouter', () => { it('should throw with invalid group', () => { expect(() => AggregateRouter.getPipeline([{ $group: { objectId: 'bar' } }])).toThrow( - new Parse.Error(Parse.Error.INVALID_QUERY, `Cannot use objectId in aggregation stage $group.`) + new Parse.Error(Parse.Error.INVALID_QUERY, `Cannot use 'objectId' in aggregation stage $group.`) ); }); }); From 82c4a3f8a95a92677523858dff52d862c4220e97 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 29 Dec 2022 14:07:53 +1100 Subject: [PATCH 09/20] Update src/Routers/AggregateRouter.js Co-authored-by: Manuel <5673677+mtrezza@users.noreply.github.com> --- src/Routers/AggregateRouter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Routers/AggregateRouter.js b/src/Routers/AggregateRouter.js index 74d20f0bc7..e855c5f971 100644 --- a/src/Routers/AggregateRouter.js +++ b/src/Routers/AggregateRouter.js @@ -104,7 +104,7 @@ export class AggregateRouter extends ClassesRouter { if (Object.prototype.hasOwnProperty.call(stage[stageName], 'objectId')) { throw new Parse.Error( Parse.Error.INVALID_QUERY, - `Cannot use objectId in aggregation stage $group.` + `Cannot use 'objectId' in aggregation stage $group.` ); } if (!Object.prototype.hasOwnProperty.call(stage[stageName], '_id')) { From 3cea14a41a57b3a38cbee8ebf3f8f7918f95bf7a Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 29 Dec 2022 14:08:00 +1100 Subject: [PATCH 10/20] Update src/Routers/AggregateRouter.js Co-authored-by: Manuel <5673677+mtrezza@users.noreply.github.com> --- src/Routers/AggregateRouter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Routers/AggregateRouter.js b/src/Routers/AggregateRouter.js index e855c5f971..7515597241 100644 --- a/src/Routers/AggregateRouter.js +++ b/src/Routers/AggregateRouter.js @@ -85,7 +85,7 @@ export class AggregateRouter extends ClassesRouter { if (keys.length !== 1) { throw new Parse.Error( Parse.Error.INVALID_QUERY, - `Pipeline stages should only have one key. Found ${keys.join(', ')}` + `Pipeline stages should only have one key but found ${keys.join(', ')}` ); } return AggregateRouter.transformStage(keys[0], stage); From b2bf0ed30fe878e6f82891fb2b0d341c0b580b71 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 29 Dec 2022 14:08:09 +1100 Subject: [PATCH 11/20] Update spec/AggregateRouter.spec.js Co-authored-by: Manuel <5673677+mtrezza@users.noreply.github.com> --- spec/AggregateRouter.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/AggregateRouter.spec.js b/spec/AggregateRouter.spec.js index 18f9345b4b..85b5a5e872 100644 --- a/spec/AggregateRouter.spec.js +++ b/spec/AggregateRouter.spec.js @@ -72,7 +72,7 @@ describe('AggregateRouter', () => { expect(() => AggregateRouter.getPipeline(body)).toThrow( new Parse.Error( Parse.Error.INVALID_QUERY, - 'Pipeline stages should only have one key. Found $group, $match' + 'Pipeline stages should only have one key but found $group, $match.' ) ); }); From 9582d27d6a3c3fbe09d8d21491dc8b8a2acc0c1b Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 29 Dec 2022 14:08:18 +1100 Subject: [PATCH 12/20] Update spec/AggregateRouter.spec.js Co-authored-by: Manuel <5673677+mtrezza@users.noreply.github.com> --- spec/AggregateRouter.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/AggregateRouter.spec.js b/spec/AggregateRouter.spec.js index 85b5a5e872..e3f7c7e50c 100644 --- a/spec/AggregateRouter.spec.js +++ b/spec/AggregateRouter.spec.js @@ -159,7 +159,7 @@ describe('AggregateRouter', () => { it('should throw with invalid stage', () => { expect(() => AggregateRouter.getPipeline([{ foo: 'bar' }])).toThrow( - new Parse.Error(Parse.Error.INVALID_QUERY, `Invalid aggregate stage: foo.`) + new Parse.Error(Parse.Error.INVALID_QUERY, `Invalid aggregate stage 'foo'.`) ); }); From 8b3dd6c5d813749387b113a4585a47b490909d5a Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 1 Jan 2023 12:32:33 +1100 Subject: [PATCH 13/20] Update AggregateRouter.spec.js --- spec/AggregateRouter.spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/AggregateRouter.spec.js b/spec/AggregateRouter.spec.js index e3f7c7e50c..f3a34729e2 100644 --- a/spec/AggregateRouter.spec.js +++ b/spec/AggregateRouter.spec.js @@ -55,7 +55,7 @@ describe('AggregateRouter', () => { expect(() => AggregateRouter.getPipeline(body)).toThrow( new Parse.Error( Parse.Error.INVALID_QUERY, - 'Pipeline stages should only have one key but found $group, $match.' + 'Pipeline stages should only have one key but found $group, $match' ) ); }); @@ -72,7 +72,7 @@ describe('AggregateRouter', () => { expect(() => AggregateRouter.getPipeline(body)).toThrow( new Parse.Error( Parse.Error.INVALID_QUERY, - 'Pipeline stages should only have one key but found $group, $match.' + 'Pipeline stages should only have one key but found $group, $match' ) ); }); @@ -159,7 +159,7 @@ describe('AggregateRouter', () => { it('should throw with invalid stage', () => { expect(() => AggregateRouter.getPipeline([{ foo: 'bar' }])).toThrow( - new Parse.Error(Parse.Error.INVALID_QUERY, `Invalid aggregate stage 'foo'.`) + new Parse.Error(Parse.Error.INVALID_QUERY, `Invalid aggregate stage: foo.`) ); }); From b04c5289a42bf46cdeb0e6bca4aa5e9e90ae6bd7 Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Thu, 5 Jan 2023 01:01:06 +0100 Subject: [PATCH 14/20] Update src/Routers/AggregateRouter.js --- src/Routers/AggregateRouter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Routers/AggregateRouter.js b/src/Routers/AggregateRouter.js index 7515597241..10996e7813 100644 --- a/src/Routers/AggregateRouter.js +++ b/src/Routers/AggregateRouter.js @@ -85,7 +85,7 @@ export class AggregateRouter extends ClassesRouter { if (keys.length !== 1) { throw new Parse.Error( Parse.Error.INVALID_QUERY, - `Pipeline stages should only have one key but found ${keys.join(', ')}` + `Pipeline stages should only have one key but found ${keys.join(', ')}.` ); } return AggregateRouter.transformStage(keys[0], stage); From 9bc344373f2a977d8c1a787c5f292008ea0902a1 Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Thu, 5 Jan 2023 01:01:12 +0100 Subject: [PATCH 15/20] Update spec/AggregateRouter.spec.js --- spec/AggregateRouter.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/AggregateRouter.spec.js b/spec/AggregateRouter.spec.js index f3a34729e2..50935050da 100644 --- a/spec/AggregateRouter.spec.js +++ b/spec/AggregateRouter.spec.js @@ -159,7 +159,7 @@ describe('AggregateRouter', () => { it('should throw with invalid stage', () => { expect(() => AggregateRouter.getPipeline([{ foo: 'bar' }])).toThrow( - new Parse.Error(Parse.Error.INVALID_QUERY, `Invalid aggregate stage: foo.`) + new Parse.Error(Parse.Error.INVALID_QUERY, `Invalid aggregate stage 'foo'.`) ); }); From 1fb9ab0b31665a61a5b658dcea579d9ed78ef39b Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Thu, 5 Jan 2023 01:01:16 +0100 Subject: [PATCH 16/20] Update spec/AggregateRouter.spec.js --- spec/AggregateRouter.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/AggregateRouter.spec.js b/spec/AggregateRouter.spec.js index 50935050da..d8cb806b42 100644 --- a/spec/AggregateRouter.spec.js +++ b/spec/AggregateRouter.spec.js @@ -72,7 +72,7 @@ describe('AggregateRouter', () => { expect(() => AggregateRouter.getPipeline(body)).toThrow( new Parse.Error( Parse.Error.INVALID_QUERY, - 'Pipeline stages should only have one key but found $group, $match' + 'Pipeline stages should only have one key but found $group, $match.' ) ); }); From f51db914a000ce22e7b5ece26b660f584de1177b Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Thu, 5 Jan 2023 01:01:21 +0100 Subject: [PATCH 17/20] Update spec/AggregateRouter.spec.js --- spec/AggregateRouter.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/AggregateRouter.spec.js b/spec/AggregateRouter.spec.js index d8cb806b42..e3f7c7e50c 100644 --- a/spec/AggregateRouter.spec.js +++ b/spec/AggregateRouter.spec.js @@ -55,7 +55,7 @@ describe('AggregateRouter', () => { expect(() => AggregateRouter.getPipeline(body)).toThrow( new Parse.Error( Parse.Error.INVALID_QUERY, - 'Pipeline stages should only have one key but found $group, $match' + 'Pipeline stages should only have one key but found $group, $match.' ) ); }); From 089d3e5449201090b2a6087b5bf15f183deaedaa Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Thu, 5 Jan 2023 01:02:01 +0100 Subject: [PATCH 18/20] Update src/Routers/AggregateRouter.js --- src/Routers/AggregateRouter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Routers/AggregateRouter.js b/src/Routers/AggregateRouter.js index 10996e7813..c69c9c40ca 100644 --- a/src/Routers/AggregateRouter.js +++ b/src/Routers/AggregateRouter.js @@ -98,7 +98,7 @@ export class AggregateRouter extends ClassesRouter { return; } if (stageName[0] !== '$') { - throw new Parse.Error(Parse.Error.INVALID_QUERY, `Invalid aggregate stage: ${stageName}.`); + throw new Parse.Error(Parse.Error.INVALID_QUERY, `Invalid aggregate stage '${stageName}'.`); } if (stageName === '$group') { if (Object.prototype.hasOwnProperty.call(stage[stageName], 'objectId')) { From b30b92e5f78f15502288496bbfaa9aec21ff5619 Mon Sep 17 00:00:00 2001 From: dblythy Date: Thu, 5 Jan 2023 12:19:28 +1100 Subject: [PATCH 19/20] Update AggregateRouter.spec.js --- spec/AggregateRouter.spec.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spec/AggregateRouter.spec.js b/spec/AggregateRouter.spec.js index e3f7c7e50c..96aedcc313 100644 --- a/spec/AggregateRouter.spec.js +++ b/spec/AggregateRouter.spec.js @@ -165,7 +165,10 @@ describe('AggregateRouter', () => { it('should throw with invalid group', () => { expect(() => AggregateRouter.getPipeline([{ $group: { objectId: 'bar' } }])).toThrow( - new Parse.Error(Parse.Error.INVALID_QUERY, `Cannot use 'objectId' in aggregation stage $group.`) + new Parse.Error( + Parse.Error.INVALID_QUERY, + `Cannot use 'objectId' in aggregation stage $group.` + ) ); }); }); From fd92dc2f876fc7bd1da9c658d4ca216ada053f6c Mon Sep 17 00:00:00 2001 From: Manuel Trezza <5673677+mtrezza@users.noreply.github.com> Date: Thu, 5 Jan 2023 15:46:50 +0100 Subject: [PATCH 20/20] Update DEPRECATIONS.md --- DEPRECATIONS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPRECATIONS.md b/DEPRECATIONS.md index 053dd9fb2b..a647782210 100644 --- a/DEPRECATIONS.md +++ b/DEPRECATIONS.md @@ -4,7 +4,7 @@ The following is a list of deprecations, according to the [Deprecation Policy](h | ID | Change | Issue | Deprecation [ℹ️][i_deprecation] | Planned Removal [ℹ️][i_removal] | Status [ℹ️][i_status] | Notes | |--------|-------------------------------------------------|----------------------------------------------------------------------|---------------------------------|---------------------------------|-----------------------|-------| -| DEPPS1 | Native MongoDB syntax in aggregation pipeline | [#7338](https://github.com/parse-community/parse-server/issues/7338) | 5.0.0 (2022) | 6.0.0 (2023) | deprecated | - | +| DEPPS1 | Native MongoDB syntax in aggregation pipeline | [#7338](https://github.com/parse-community/parse-server/issues/7338) | 5.0.0 (2022) | 6.0.0 (2023) | removed | - | | DEPPS2 | Config option `directAccess` defaults to `true` | [#6636](https://github.com/parse-community/parse-server/pull/6636) | 5.0.0 (2022) | 6.0.0 (2023) | removed | - | | DEPPS3 | Config option `enforcePrivateUsers` defaults to `true` | [#7319](https://github.com/parse-community/parse-server/pull/7319) | 5.0.0 (2022) | 6.0.0 (2023) | removed | - | | DEPPS4 | Remove convenience method for http request `Parse.Cloud.httpRequest` | [#7589](https://github.com/parse-community/parse-server/pull/7589) | 5.0.0 (2022) | 6.0.0 (2023) | removed | - |