feat: Add Node 22 support (#9187)
This commit is contained in:
18
.github/workflows/ci.yml
vendored
18
.github/workflows/ci.yml
vendored
@@ -143,32 +143,36 @@ jobs:
|
||||
- name: MongoDB 4.2, ReplicaSet
|
||||
MONGODB_VERSION: 4.2.25
|
||||
MONGODB_TOPOLOGY: replset
|
||||
NODE_VERSION: 20.12.0
|
||||
NODE_VERSION: 22
|
||||
- name: MongoDB 4.4, ReplicaSet
|
||||
MONGODB_VERSION: 4.4.29
|
||||
MONGODB_TOPOLOGY: replset
|
||||
NODE_VERSION: 20.12.0
|
||||
NODE_VERSION: 22
|
||||
- name: MongoDB 5, ReplicaSet
|
||||
MONGODB_VERSION: 5.0.26
|
||||
MONGODB_TOPOLOGY: replset
|
||||
NODE_VERSION: 20.12.0
|
||||
NODE_VERSION: 22
|
||||
- name: MongoDB 6, ReplicaSet
|
||||
MONGODB_VERSION: 6.0.14
|
||||
MONGODB_TOPOLOGY: replset
|
||||
NODE_VERSION: 20.12.0
|
||||
NODE_VERSION: 22
|
||||
- name: MongoDB 7, ReplicaSet
|
||||
MONGODB_VERSION: 7.0.8
|
||||
MONGODB_TOPOLOGY: replset
|
||||
NODE_VERSION: 20.12.0
|
||||
NODE_VERSION: 22
|
||||
- name: Redis Cache
|
||||
PARSE_SERVER_TEST_CACHE: redis
|
||||
MONGODB_VERSION: 7.0.8
|
||||
MONGODB_TOPOLOGY: standalone
|
||||
NODE_VERSION: 20.12.0
|
||||
NODE_VERSION: 22
|
||||
- name: Node 18
|
||||
MONGODB_VERSION: 7.0.8
|
||||
MONGODB_TOPOLOGY: standalone
|
||||
NODE_VERSION: 18.20.0
|
||||
NODE_VERSION: 18
|
||||
- name: Node 20
|
||||
MONGODB_VERSION: 7.0.8
|
||||
MONGODB_TOPOLOGY: standalone
|
||||
NODE_VERSION: 20
|
||||
fail-fast: false
|
||||
name: ${{ matrix.name }}
|
||||
timeout-minutes: 15
|
||||
|
||||
23
README.md
23
README.md
@@ -9,7 +9,7 @@
|
||||
[](https://app.codecov.io/github/parse-community/parse-server/tree/alpha)
|
||||
[](https://github.com/parse-community/parse-dashboard/releases)
|
||||
|
||||
[](https://nodejs.org)
|
||||
[](https://nodejs.org)
|
||||
[](https://www.mongodb.com)
|
||||
[](https://www.postgresql.org)
|
||||
|
||||
@@ -127,22 +127,23 @@ Before you start make sure you have installed:
|
||||
|
||||
Parse Server is continuously tested with the most recent releases of Node.js to ensure compatibility. We follow the [Node.js Long Term Support plan](https://github.com/nodejs/Release) and only test against versions that are officially supported and have not reached their end-of-life date.
|
||||
|
||||
| Version | Latest Version | End-of-Life | Compatible |
|
||||
|------------|----------------|-------------|------------|
|
||||
| Node.js 18 | 18.20.0 | April 2025 | ✅ Yes |
|
||||
| Node.js 20 | 20.12.0 | April 2026 | ✅ Yes |
|
||||
| Version | End-of-Life | Compatible |
|
||||
|------------|-------------|------------|
|
||||
| Node.js 18 | April 2025 | ✅ Yes |
|
||||
| Node.js 20 | April 2026 | ✅ Yes |
|
||||
| Node.js 22 | April 2027 | ✅ Yes |
|
||||
|
||||
#### MongoDB
|
||||
|
||||
Parse Server is continuously tested with the most recent releases of MongoDB to ensure compatibility. We follow the [MongoDB support schedule](https://www.mongodb.com/support-policy) and [MongoDB lifecycle schedule](https://www.mongodb.com/support-policy/lifecycles) and only test against versions that are officially supported and have not reached their end-of-life date. MongoDB "rapid releases" are ignored as these are considered pre-releases of the next major version.
|
||||
|
||||
| Version | Latest Version | End-of-Life | Compatible |
|
||||
| ----------- | -------------- | ------------- | ---------- |
|
||||
| MongoDB 4.2 | 4.2.25 | April 2023 | ✅ Yes |
|
||||
| MongoDB 4.4 | 4.4.29 | February 2024 | ✅ Yes |
|
||||
| MongoDB 5 | 5.0.26 | October 2024 | ✅ Yes |
|
||||
| MongoDB 6 | 6.0.14 | July 2025 | ✅ Yes |
|
||||
| MongoDB 7 | 7.0.8 | TDB | ✅ Yes |
|
||||
|-------------|----------------|---------------|------------|
|
||||
| MongoDB 4.2 | 4.2.25 | April 2023 | ✅ Yes |
|
||||
| MongoDB 4.4 | 4.4.29 | February 2024 | ✅ Yes |
|
||||
| MongoDB 5 | 5.0.26 | October 2024 | ✅ Yes |
|
||||
| MongoDB 6 | 6.0.14 | July 2025 | ✅ Yes |
|
||||
| MongoDB 7 | 7.0.8 | TDB | ✅ Yes |
|
||||
|
||||
#### PostgreSQL
|
||||
|
||||
|
||||
76
package-lock.json
generated
76
package-lock.json
generated
@@ -45,6 +45,7 @@
|
||||
"pg-monitor": "2.0.0",
|
||||
"pg-promise": "11.7.8",
|
||||
"pluralize": "8.0.0",
|
||||
"punycode": "2.3.1",
|
||||
"rate-limit-redis": "4.2.0",
|
||||
"redis": "4.6.13",
|
||||
"semver": "7.6.0",
|
||||
@@ -102,7 +103,7 @@
|
||||
"yaml": "1.10.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21"
|
||||
"node": "18 || 19 || 20 || 22"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
@@ -13534,15 +13535,6 @@
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/mongodb-runner/node_modules/punycode": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/mongodb-runner/node_modules/tr46": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz",
|
||||
@@ -18026,9 +18018,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||
"integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/qs": {
|
||||
"version": "6.11.0",
|
||||
@@ -20426,6 +20422,11 @@
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/tough-cookie/node_modules/punycode": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||
"integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
|
||||
@@ -20437,14 +20438,6 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46/node_modules/punycode": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/traverse": {
|
||||
"version": "0.6.7",
|
||||
"resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz",
|
||||
@@ -20831,14 +20824,6 @@
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/uri-js/node_modules/punycode": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/url-join": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz",
|
||||
@@ -31317,12 +31302,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"punycode": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
|
||||
"dev": true
|
||||
},
|
||||
"tr46": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz",
|
||||
@@ -34465,9 +34444,9 @@
|
||||
}
|
||||
},
|
||||
"punycode": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||
"integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.11.0",
|
||||
@@ -36222,6 +36201,13 @@
|
||||
"requires": {
|
||||
"psl": "^1.1.24",
|
||||
"punycode": "^1.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"punycode": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||
"integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"tr46": {
|
||||
@@ -36230,13 +36216,6 @@
|
||||
"integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
|
||||
"requires": {
|
||||
"punycode": "^2.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"punycode": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"traverse": {
|
||||
@@ -36509,13 +36488,6 @@
|
||||
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
|
||||
"requires": {
|
||||
"punycode": "^2.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"punycode": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"url-join": {
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
"pg-monitor": "2.0.0",
|
||||
"pg-promise": "11.7.8",
|
||||
"pluralize": "8.0.0",
|
||||
"punycode": "2.3.1",
|
||||
"rate-limit-redis": "4.2.0",
|
||||
"redis": "4.6.13",
|
||||
"semver": "7.6.0",
|
||||
@@ -138,7 +139,7 @@
|
||||
"madge:circular": "node_modules/.bin/madge ./src --circular"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21"
|
||||
"node": "18 || 19 || 20 || 22"
|
||||
},
|
||||
"bin": {
|
||||
"parse-server": "bin/parse-server"
|
||||
|
||||
101
spec/CLI.spec.js
101
spec/CLI.spec.js
@@ -207,6 +207,36 @@ describe('LiveQuery definitions', () => {
|
||||
describe('execution', () => {
|
||||
const binPath = path.resolve(__dirname, '../bin/parse-server');
|
||||
let childProcess;
|
||||
let aggregatedData;
|
||||
|
||||
function handleStdout(childProcess, done, aggregatedData, requiredData) {
|
||||
childProcess.stdout.on('data', data => {
|
||||
data = data.toString();
|
||||
aggregatedData.push(data);
|
||||
if (requiredData.every(required => aggregatedData.some(aggregated => aggregated.includes(required)))) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleStderr(childProcess, done) {
|
||||
childProcess.stderr.on('data', data => {
|
||||
data = data.toString();
|
||||
if (!data.includes('[DEP0040] DeprecationWarning')) {
|
||||
done.fail(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleError(childProcess, done) {
|
||||
childProcess.on('error', err => {
|
||||
done.fail(err);
|
||||
});
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
aggregatedData = [];
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
if (childProcess) {
|
||||
@@ -220,26 +250,20 @@ describe('execution', () => {
|
||||
|
||||
it('should start Parse Server', done => {
|
||||
const env = { ...process.env };
|
||||
env.NODE_OPTIONS = '--dns-result-order=ipv4first';
|
||||
env.NODE_OPTIONS = '--dns-result-order=ipv4first --trace-deprecation';
|
||||
childProcess = spawn(
|
||||
binPath,
|
||||
['--appId', 'test', '--masterKey', 'test', '--databaseURI', databaseURI, '--port', '1339'],
|
||||
{ env }
|
||||
);
|
||||
childProcess.stdout.on('data', data => {
|
||||
data = data.toString();
|
||||
if (data.includes('parse-server running on')) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
childProcess.stderr.on('data', data => {
|
||||
done.fail(data.toString());
|
||||
});
|
||||
handleStdout(childProcess, done, aggregatedData, ['parse-server running on']);
|
||||
handleStderr(childProcess, done);
|
||||
handleError(childProcess, done);
|
||||
});
|
||||
|
||||
it('should start Parse Server with GraphQL', async done => {
|
||||
const env = { ...process.env };
|
||||
env.NODE_OPTIONS = '--dns-result-order=ipv4first';
|
||||
env.NODE_OPTIONS = '--dns-result-order=ipv4first --trace-deprecation';
|
||||
childProcess = spawn(
|
||||
binPath,
|
||||
[
|
||||
@@ -255,23 +279,17 @@ describe('execution', () => {
|
||||
],
|
||||
{ env }
|
||||
);
|
||||
let output = '';
|
||||
childProcess.stdout.on('data', data => {
|
||||
data = data.toString();
|
||||
output += data;
|
||||
if (data.includes('GraphQL running on')) {
|
||||
expect(output).toMatch('parse-server running on');
|
||||
done();
|
||||
}
|
||||
});
|
||||
childProcess.stderr.on('data', data => {
|
||||
done.fail(data.toString());
|
||||
});
|
||||
handleStdout(childProcess, done, aggregatedData, [
|
||||
'parse-server running on',
|
||||
'GraphQL running on',
|
||||
]);
|
||||
handleStderr(childProcess, done);
|
||||
handleError(childProcess, done);
|
||||
});
|
||||
|
||||
it('should start Parse Server with GraphQL and Playground', async done => {
|
||||
const env = { ...process.env };
|
||||
env.NODE_OPTIONS = '--dns-result-order=ipv4first';
|
||||
env.NODE_OPTIONS = '--dns-result-order=ipv4first --trace-deprecation';
|
||||
childProcess = spawn(
|
||||
binPath,
|
||||
[
|
||||
@@ -288,38 +306,25 @@ describe('execution', () => {
|
||||
],
|
||||
{ env }
|
||||
);
|
||||
let output = '';
|
||||
childProcess.stdout.on('data', data => {
|
||||
data = data.toString();
|
||||
output += data;
|
||||
if (data.includes('Playground running on')) {
|
||||
expect(output).toMatch('GraphQL running on');
|
||||
expect(output).toMatch('parse-server running on');
|
||||
done();
|
||||
}
|
||||
});
|
||||
childProcess.stderr.on('data', data => {
|
||||
done.fail(data.toString());
|
||||
});
|
||||
handleStdout(childProcess, done, aggregatedData, [
|
||||
'parse-server running on',
|
||||
'Playground running on',
|
||||
'GraphQL running on',
|
||||
]);
|
||||
handleStderr(childProcess, done);
|
||||
handleError(childProcess, done);
|
||||
});
|
||||
|
||||
it('can start Parse Server with auth via CLI', done => {
|
||||
const env = { ...process.env };
|
||||
env.NODE_OPTIONS = '--dns-result-order=ipv4first';
|
||||
env.NODE_OPTIONS = '--dns-result-order=ipv4first --trace-deprecation';
|
||||
childProcess = spawn(
|
||||
binPath,
|
||||
['--databaseURI', databaseURI, './spec/configs/CLIConfigAuth.json'],
|
||||
{ env }
|
||||
);
|
||||
childProcess.stdout.on('data', data => {
|
||||
data = data.toString();
|
||||
if (data.includes('parse-server running on')) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
childProcess.stderr.on('data', data => {
|
||||
data = data.toString();
|
||||
done.fail(data.toString());
|
||||
});
|
||||
handleStdout(childProcess, done, aggregatedData, ['parse-server running on']);
|
||||
handleStderr(childProcess, done);
|
||||
handleError(childProcess, done);
|
||||
});
|
||||
});
|
||||
|
||||
2
src/vendor/mongodbUrl.js
vendored
2
src/vendor/mongodbUrl.js
vendored
@@ -5,7 +5,7 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const punycode = require('punycode');
|
||||
import punycode from 'punycode/punycode.js';
|
||||
|
||||
exports.parse = urlParse;
|
||||
exports.resolve = urlResolve;
|
||||
|
||||
Reference in New Issue
Block a user