From 847a274cdb8c22f8e0fc249162e5e2c9e29a594a Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Sun, 13 Jul 2025 02:44:08 +0200 Subject: [PATCH 1/6] fix: MongoDB aggregation pipeline with `$dateSubtract` from `$$NOW` returns no results (#9822) --- spec/ParseQuery.Aggregate.spec.js | 30 +++++++++++++++++++ .../Storage/Mongo/MongoStorageAdapter.js | 25 +++++++++------- 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/spec/ParseQuery.Aggregate.spec.js b/spec/ParseQuery.Aggregate.spec.js index d255f301..d75658b1 100644 --- a/spec/ParseQuery.Aggregate.spec.js +++ b/spec/ParseQuery.Aggregate.spec.js @@ -439,6 +439,36 @@ describe('Parse.Query Aggregate testing', () => { } ); + it_id('3723671d-4100-4103-ad9c-60e4c22e20ff')(it_exclude_dbs(['postgres']))('matches expression with $dateSubtract from $$NOW', async () => { + const obj1 = new TestObject({ date: new Date(new Date().getTime() - 1 * 24 * 60 * 60 * 1_000) }); // 1 day ago + const obj2 = new TestObject({ date: new Date(new Date().getTime() - 2 * 24 * 60 * 60 * 1_000) }); // 3 days ago + await Parse.Object.saveAll([obj1, obj2]); + + const pipeline = [ + { + $match: { + $expr: { + $gte: [ + '$date', + { + $dateSubtract: { + startDate: '$$NOW', + unit: 'day', + amount: 2, + }, + }, + ], + }, + }, + }, + ]; + + const query = new Parse.Query('TestObject'); + const results = await query.aggregate(pipeline, { useMasterKey: true }); + expect(results.length).toBe(1); + expect(new Date(results[0].date.iso)).toEqual(obj1.get('date')); + }); + it_only_db('postgres')( 'can group by any date field (it does not work if you have dirty data)', // rows in your collection with non date data in the field that is supposed to be a date done => { diff --git a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js index fc6c5556..2c82a201 100644 --- a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -960,23 +960,28 @@ export class MongoStorageAdapter implements StorageAdapter { return pipeline; } - // This function will attempt to convert the provided value to a Date object. Since this is part - // of an aggregation pipeline, the value can either be a string or it can be another object with - // an operator in it (like $gt, $lt, etc). Because of this I felt it was easier to make this a - // recursive method to traverse down to the "leaf node" which is going to be the string. + /** + * Recursively converts values to Date objects. Since the passed object is part of an aggregation + * pipeline and can contain various logic operators (like $gt, $lt, etc), this function will + * traverse the object and convert any strings that can be parsed as dates into Date objects. + * @param {any} value The value to convert. + * @returns {any} The original value if not convertible to Date, or a Date object if it is. + */ _convertToDate(value: any): any { if (value instanceof Date) { return value; } if (typeof value === 'string') { - return new Date(value); + return isNaN(Date.parse(value)) ? value : new Date(value); } - - const returnValue = {}; - for (const field in value) { - returnValue[field] = this._convertToDate(value[field]); + if (typeof value === 'object') { + const returnValue = {}; + for (const field in value) { + returnValue[field] = this._convertToDate(value[field]); + } + return returnValue; } - return returnValue; + return value; } _parseReadPreference(readPreference: ?string): ?string { From 9c6d7ab4f10d36259eede8344d1c716f0bf5a266 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sun, 13 Jul 2025 00:44:59 +0000 Subject: [PATCH 2/6] chore(release): 8.2.3-alpha.1 [skip ci] ## [8.2.3-alpha.1](https://github.com/parse-community/parse-server/compare/8.2.2...8.2.3-alpha.1) (2025-07-13) ### Bug Fixes * MongoDB aggregation pipeline with `$dateSubtract` from `$$NOW` returns no results ([#9822](https://github.com/parse-community/parse-server/issues/9822)) ([847a274](https://github.com/parse-community/parse-server/commit/847a274cdb8c22f8e0fc249162e5e2c9e29a594a)) --- changelogs/CHANGELOG_alpha.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/changelogs/CHANGELOG_alpha.md b/changelogs/CHANGELOG_alpha.md index b5aa0e11..5693bc58 100644 --- a/changelogs/CHANGELOG_alpha.md +++ b/changelogs/CHANGELOG_alpha.md @@ -1,3 +1,10 @@ +## [8.2.3-alpha.1](https://github.com/parse-community/parse-server/compare/8.2.2...8.2.3-alpha.1) (2025-07-13) + + +### Bug Fixes + +* MongoDB aggregation pipeline with `$dateSubtract` from `$$NOW` returns no results ([#9822](https://github.com/parse-community/parse-server/issues/9822)) ([847a274](https://github.com/parse-community/parse-server/commit/847a274cdb8c22f8e0fc249162e5e2c9e29a594a)) + ## [8.2.2-alpha.1](https://github.com/parse-community/parse-server/compare/8.2.1...8.2.2-alpha.1) (2025-07-10) diff --git a/package-lock.json b/package-lock.json index 376914ab..ac60b767 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "parse-server", - "version": "8.2.2", + "version": "8.2.3-alpha.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "parse-server", - "version": "8.2.2", + "version": "8.2.3-alpha.1", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index e36ec661..d220f6c7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "parse-server", - "version": "8.2.2", + "version": "8.2.3-alpha.1", "description": "An express module providing a Parse-compatible API server", "main": "lib/index.js", "repository": { From dfffc14a5473fe88532b66dc77a5d230edbe48f0 Mon Sep 17 00:00:00 2001 From: Parse Platform <90459499+parseplatformorg@users.noreply.github.com> Date: Tue, 15 Jul 2025 15:37:21 +0200 Subject: [PATCH 3/6] refactor: Upgrade pg-promise from 11.13.0 to 11.14.0 (#9825) --- package-lock.json | 50 +++++++++++++++++++++++------------------------ package.json | 2 +- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/package-lock.json b/package-lock.json index ac60b767..2ceac3cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@apollo/server": "^4.12.1", + "@apollo/server": "4.12.1", "@babel/eslint-parser": "7.27.1", "@graphql-tools/merge": "9.0.24", "@graphql-tools/schema": "10.0.23", @@ -42,7 +42,7 @@ "parse": "6.1.1", "path-to-regexp": "6.3.0", "pg-monitor": "3.0.0", - "pg-promise": "11.13.0", + "pg-promise": "^11.14.0", "pluralize": "8.0.0", "punycode": "2.3.1", "rate-limit-redis": "4.2.0", @@ -7704,12 +7704,12 @@ } }, "node_modules/assert-options": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/assert-options/-/assert-options-0.8.2.tgz", - "integrity": "sha512-XaXoMxY0zuwAb0YuZjxIm8FeWvNq0aWNIbrzHhFjme8Smxw4JlPoyrAKQ6808k5UvQdhvnWqHZCphq5mXd4TDA==", + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/assert-options/-/assert-options-0.8.3.tgz", + "integrity": "sha512-s6v4HnA+vYSGO4eZX+F+I3gvF74wPk+m6Z1Q3w1Dsg4Pnv/R24vhKAasoMVZGvDpOOfTg1Qz4ptZnEbuy95XsQ==", "license": "MIT", "engines": { - "node": ">=10.0.0" + "node": ">=14.0.0" } }, "node_modules/assert-plus": { @@ -18771,15 +18771,15 @@ } }, "node_modules/pg-promise": { - "version": "11.13.0", - "resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-11.13.0.tgz", - "integrity": "sha512-NWCsh1gnELfYRF5hNhfXPcSxuCk9C3FyM9MhmGkVTmepczAC2aXuBkyXhipVlHzp0V/IVzyCZOrlH48Ma3i7YQ==", + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-11.14.0.tgz", + "integrity": "sha512-x/HZ6hK0MxYllyfUbmN/XZc7JBYoow7KElyNW9hnlhgRHMiRZmRUtfNM/wcuElpjSoASPxkoIKi4IA5QlwOONA==", "license": "MIT", "dependencies": { - "assert-options": "0.8.2", + "assert-options": "0.8.3", "pg": "8.14.1", "pg-minify": "1.7.0", - "spex": "3.4.0" + "spex": "3.4.1" }, "engines": { "node": ">=14.0" @@ -20938,9 +20938,9 @@ "dev": true }, "node_modules/spex": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/spex/-/spex-3.4.0.tgz", - "integrity": "sha512-8JeZJ7QlEBnSj1W1fKXgbB2KUPA8k4BxFMf6lZX/c1ZagU/1b9uZWZK0yD6yjfzqAIuTNG4YlRmtMpQiXuohsg==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/spex/-/spex-3.4.1.tgz", + "integrity": "sha512-Br0Mu3S+c70kr4keXF+6K4B8ohR+aJjI9s7SbdsI3hliE1Riz4z+FQk7FQL+r7X1t90KPkpuKwQyITpCIQN9mg==", "license": "MIT", "engines": { "node": ">=14.0.0" @@ -28087,9 +28087,9 @@ } }, "assert-options": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/assert-options/-/assert-options-0.8.2.tgz", - "integrity": "sha512-XaXoMxY0zuwAb0YuZjxIm8FeWvNq0aWNIbrzHhFjme8Smxw4JlPoyrAKQ6808k5UvQdhvnWqHZCphq5mXd4TDA==" + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/assert-options/-/assert-options-0.8.3.tgz", + "integrity": "sha512-s6v4HnA+vYSGO4eZX+F+I3gvF74wPk+m6Z1Q3w1Dsg4Pnv/R24vhKAasoMVZGvDpOOfTg1Qz4ptZnEbuy95XsQ==" }, "assert-plus": { "version": "1.0.0", @@ -35796,14 +35796,14 @@ "requires": {} }, "pg-promise": { - "version": "11.13.0", - "resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-11.13.0.tgz", - "integrity": "sha512-NWCsh1gnELfYRF5hNhfXPcSxuCk9C3FyM9MhmGkVTmepczAC2aXuBkyXhipVlHzp0V/IVzyCZOrlH48Ma3i7YQ==", + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-11.14.0.tgz", + "integrity": "sha512-x/HZ6hK0MxYllyfUbmN/XZc7JBYoow7KElyNW9hnlhgRHMiRZmRUtfNM/wcuElpjSoASPxkoIKi4IA5QlwOONA==", "requires": { - "assert-options": "0.8.2", + "assert-options": "0.8.3", "pg": "8.14.1", "pg-minify": "1.7.0", - "spex": "3.4.0" + "spex": "3.4.1" } }, "pg-protocol": { @@ -37327,9 +37327,9 @@ "dev": true }, "spex": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/spex/-/spex-3.4.0.tgz", - "integrity": "sha512-8JeZJ7QlEBnSj1W1fKXgbB2KUPA8k4BxFMf6lZX/c1ZagU/1b9uZWZK0yD6yjfzqAIuTNG4YlRmtMpQiXuohsg==" + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/spex/-/spex-3.4.1.tgz", + "integrity": "sha512-Br0Mu3S+c70kr4keXF+6K4B8ohR+aJjI9s7SbdsI3hliE1Riz4z+FQk7FQL+r7X1t90KPkpuKwQyITpCIQN9mg==" }, "split2": { "version": "4.2.0", diff --git a/package.json b/package.json index d220f6c7..8abcb6b2 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "parse": "6.1.1", "path-to-regexp": "6.3.0", "pg-monitor": "3.0.0", - "pg-promise": "11.13.0", + "pg-promise": "11.14.0", "pluralize": "8.0.0", "punycode": "2.3.1", "rate-limit-redis": "4.2.0", From 4e301a5fffcd77ec405e530c9fba499571e898f1 Mon Sep 17 00:00:00 2001 From: Parse Platform <90459499+parseplatformorg@users.noreply.github.com> Date: Fri, 18 Jul 2025 01:28:11 +0200 Subject: [PATCH 4/6] refactor: Upgrade express-rate-limit from 7.5.0 to 7.5.1 (#9824) --- package-lock.json | 16 ++++++++-------- package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2ceac3cf..1d53ca18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "cors": "2.8.5", "deepcopy": "2.1.0", "express": "5.1.0", - "express-rate-limit": "7.5.0", + "express-rate-limit": "^7.5.1", "follow-redirects": "1.15.9", "graphql": "16.11.0", "graphql-list-fields": "2.0.4", @@ -10579,9 +10579,9 @@ } }, "node_modules/express-rate-limit": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz", - "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz", + "integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==", "license": "MIT", "engines": { "node": ">= 16" @@ -10590,7 +10590,7 @@ "url": "https://github.com/sponsors/express-rate-limit" }, "peerDependencies": { - "express": "^4.11 || 5 || ^5.0.0-beta.1" + "express": ">= 4.11" } }, "node_modules/express/node_modules/mime-db": { @@ -30147,9 +30147,9 @@ } }, "express-rate-limit": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz", - "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz", + "integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==", "requires": {} }, "extend": { diff --git a/package.json b/package.json index 8abcb6b2..d6648d88 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "cors": "2.8.5", "deepcopy": "2.1.0", "express": "5.1.0", - "express-rate-limit": "7.5.0", + "express-rate-limit": "7.5.1", "follow-redirects": "1.15.9", "graphql": "16.11.0", "graphql-list-fields": "2.0.4", From 3d8dc5fa0dc2d1b22ac1832c7e32a2169dd53373 Mon Sep 17 00:00:00 2001 From: Parse Platform <90459499+parseplatformorg@users.noreply.github.com> Date: Wed, 30 Jul 2025 00:37:51 +0200 Subject: [PATCH 5/6] refactor: Upgrade @babel/eslint-parser from 7.27.1 to 7.28.0 (#9835) --- package-lock.json | 18 +++++++++--------- package.json | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1d53ca18..9385dd1f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "license": "Apache-2.0", "dependencies": { "@apollo/server": "4.12.1", - "@babel/eslint-parser": "7.27.1", + "@babel/eslint-parser": "^7.28.0", "@graphql-tools/merge": "9.0.24", "@graphql-tools/schema": "10.0.23", "@graphql-tools/utils": "10.8.6", @@ -22,7 +22,7 @@ "cors": "2.8.5", "deepcopy": "2.1.0", "express": "5.1.0", - "express-rate-limit": "^7.5.1", + "express-rate-limit": "7.5.1", "follow-redirects": "1.15.9", "graphql": "16.11.0", "graphql-list-fields": "2.0.4", @@ -42,7 +42,7 @@ "parse": "6.1.1", "path-to-regexp": "6.3.0", "pg-monitor": "3.0.0", - "pg-promise": "^11.14.0", + "pg-promise": "11.14.0", "pluralize": "8.0.0", "punycode": "2.3.1", "rate-limit-redis": "4.2.0", @@ -900,9 +900,9 @@ } }, "node_modules/@babel/eslint-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.27.1.tgz", - "integrity": "sha512-q8rjOuadH0V6Zo4XLMkJ3RMQ9MSBqwaDByyYB0izsYdaIWGNLmEblbCOf1vyFHICcg16CD7Fsi51vcQnYxmt6Q==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.28.0.tgz", + "integrity": "sha512-N4ntErOlKvcbTt01rr5wj3y55xnIdx1ymrfIr8C2WnM1Y9glFgWaGDEULJIazOX3XM9NRzhfJ6zZnQ1sBNWU+w==", "license": "MIT", "dependencies": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", @@ -23422,9 +23422,9 @@ } }, "@babel/eslint-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.27.1.tgz", - "integrity": "sha512-q8rjOuadH0V6Zo4XLMkJ3RMQ9MSBqwaDByyYB0izsYdaIWGNLmEblbCOf1vyFHICcg16CD7Fsi51vcQnYxmt6Q==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.28.0.tgz", + "integrity": "sha512-N4ntErOlKvcbTt01rr5wj3y55xnIdx1ymrfIr8C2WnM1Y9glFgWaGDEULJIazOX3XM9NRzhfJ6zZnQ1sBNWU+w==", "requires": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", "eslint-visitor-keys": "^2.1.0", diff --git a/package.json b/package.json index d6648d88..c5a6c5e8 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "license": "Apache-2.0", "dependencies": { "@apollo/server": "4.12.1", - "@babel/eslint-parser": "7.27.1", + "@babel/eslint-parser": "7.28.0", "@graphql-tools/merge": "9.0.24", "@graphql-tools/schema": "10.0.23", "@graphql-tools/utils": "10.8.6",