From abe43a06b3005338805c476dbf72c25790d57a7f Mon Sep 17 00:00:00 2001 From: dblythy Date: Fri, 14 Oct 2022 12:11:01 +1100 Subject: [PATCH 001/104] feat: Parse Server async initialization --- spec/CloudCode.spec.js | 42 ++++++++ spec/DefinedSchemas.spec.js | 2 +- spec/ParseLiveQueryServer.spec.js | 32 ++---- spec/cloud/cloudCodeModuleFile.js | 3 + spec/helper.js | 66 +++++------- spec/index.spec.js | 138 ++++++++++++------------- src/Options/Definitions.js | 4 - src/Options/docs.js | 1 - src/Options/index.js | 2 - src/ParseServer.js | 90 ++++++++-------- src/SchemaMigrations/DefinedSchemas.js | 11 +- src/middlewares.js | 7 +- 12 files changed, 207 insertions(+), 191 deletions(-) create mode 100644 spec/cloud/cloudCodeModuleFile.js diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index bf1a2c8c42..e33e63ff27 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -1,6 +1,7 @@ 'use strict'; const Config = require('../lib/Config'); const Parse = require('parse/node'); +const ParseServer = require('../lib/index').ParseServer; const request = require('../lib/request'); const InMemoryCacheAdapter = require('../lib/Adapters/Cache/InMemoryCacheAdapter') .InMemoryCacheAdapter; @@ -39,6 +40,47 @@ describe('Cloud Code', () => { }); }); + it('can load cloud code as a module', async () => { + process.env.npm_package_type = 'module'; + await reconfigureServer({ cloud: './spec/cloud/cloudCodeModuleFile.js' }); + const result = await Parse.Cloud.run('cloudCodeInFile'); + expect(result).toEqual('It is possible to define cloud code in a file.'); + delete process.env.npm_package_type; + }); + + it('cloud code must be valid type', async () => { + await expectAsync(reconfigureServer({ cloud: true })).toBeRejectedWith( + "argument 'cloud' must either be a string or a function" + ); + }); + + it('should wait for cloud code to load', async () => { + const initiated = new Date(); + const parseServer = await new ParseServer({ + appId: 'test2', + masterKey: 'abc', + serverURL: 'http://localhost:12668/parse', + silent: true, + async cloud() { + await new Promise(resolve => setTimeout(resolve, 1000)); + Parse.Cloud.beforeSave('Test', () => { + throw 'Cannot save.'; + }); + }, + }).start(); + const express = require('express'); + const app = express(); + app.use('/parse', parseServer); + const server = app.listen(12668); + + const now = new Date(); + expect(now.getTime() - initiated.getTime() > 1000).toBeTrue(); + await expectAsync(new Parse.Object('Test').save()).toBeRejectedWith( + new Parse.Error(141, 'Cannot save.') + ); + await new Promise(resolve => server.close(resolve)); + }); + it('can create functions', done => { Parse.Cloud.define('hello', () => { return 'Hello world!'; diff --git a/spec/DefinedSchemas.spec.js b/spec/DefinedSchemas.spec.js index 0b1f2a3443..98b3d1e9d9 100644 --- a/spec/DefinedSchemas.spec.js +++ b/spec/DefinedSchemas.spec.js @@ -631,7 +631,7 @@ describe('DefinedSchemas', () => { const logger = require('../lib/logger').logger; spyOn(DefinedSchemas.prototype, 'wait').and.resolveTo(); spyOn(logger, 'error').and.callThrough(); - spyOn(Parse.Schema, 'all').and.callFake(() => { + spyOn(DefinedSchemas.prototype, 'createDeleteSession').and.callFake(() => { throw error; }); diff --git a/spec/ParseLiveQueryServer.spec.js b/spec/ParseLiveQueryServer.spec.js index 0d1a1e6387..587b2ace87 100644 --- a/spec/ParseLiveQueryServer.spec.js +++ b/spec/ParseLiveQueryServer.spec.js @@ -115,8 +115,8 @@ describe('ParseLiveQueryServer', function () { }); describe_only_db('mongo')('initialization', () => { - it('can be initialized through ParseServer without liveQueryServerOptions', function (done) { - const parseServer = ParseServer.start({ + it('can be initialized through ParseServer without liveQueryServerOptions', async () => { + const parseServer = await ParseServer.start({ appId: 'hello', masterKey: 'world', port: 22345, @@ -126,19 +126,14 @@ describe('ParseLiveQueryServer', function () { classNames: ['Yolo'], }, startLiveQueryServer: true, - serverStartComplete: () => { - expect(parseServer.liveQueryServer).not.toBeUndefined(); - expect(parseServer.liveQueryServer.server).toBe(parseServer.server); - parseServer.server.close(async () => { - await reconfigureServer(); - done(); - }); - }, }); + expect(parseServer.liveQueryServer).not.toBeUndefined(); + expect(parseServer.liveQueryServer.server).toBe(parseServer.server); + await new Promise(resolve => parseServer.server.close(resolve)); }); - it('can be initialized through ParseServer with liveQueryServerOptions', function (done) { - const parseServer = ParseServer.start({ + it('can be initialized through ParseServer with liveQueryServerOptions', async () => { + const parseServer = await ParseServer.start({ appId: 'hello', masterKey: 'world', port: 22346, @@ -150,17 +145,10 @@ describe('ParseLiveQueryServer', function () { liveQueryServerOptions: { port: 22347, }, - serverStartComplete: () => { - expect(parseServer.liveQueryServer).not.toBeUndefined(); - expect(parseServer.liveQueryServer.server).not.toBe(parseServer.server); - parseServer.liveQueryServer.server.close( - parseServer.server.close.bind(parseServer.server, async () => { - await reconfigureServer(); - done(); - }) - ); - }, }); + expect(parseServer.liveQueryServer).not.toBeUndefined(); + expect(parseServer.liveQueryServer.server).not.toBe(parseServer.server); + await new Promise(resolve => parseServer.server.close(resolve)); }); }); diff --git a/spec/cloud/cloudCodeModuleFile.js b/spec/cloud/cloudCodeModuleFile.js new file mode 100644 index 0000000000..a62b4fcc24 --- /dev/null +++ b/spec/cloud/cloudCodeModuleFile.js @@ -0,0 +1,3 @@ +Parse.Cloud.define('cloudCodeInFile', () => { + return 'It is possible to define cloud code in a file.'; +}); diff --git a/spec/helper.js b/spec/helper.js index f769c0f521..8c9abd2c39 100644 --- a/spec/helper.js +++ b/spec/helper.js @@ -148,46 +148,32 @@ let server; let didChangeConfiguration = false; // Allows testing specific configurations of Parse Server -const reconfigureServer = (changedConfiguration = {}) => { - return new Promise((resolve, reject) => { - if (server) { - return server.close(() => { - server = undefined; - reconfigureServer(changedConfiguration).then(resolve, reject); - }); - } - try { - let parseServer = undefined; - didChangeConfiguration = Object.keys(changedConfiguration).length !== 0; - const newConfiguration = Object.assign({}, defaultConfiguration, changedConfiguration, { - serverStartComplete: error => { - if (error) { - reject(error); - } else { - Parse.CoreManager.setRESTController(RESTController); - resolve(parseServer); - } - }, - mountPath: '/1', - port, - }); - cache.clear(); - parseServer = ParseServer.start(newConfiguration); - parseServer.expressApp.use('/1', err => { - console.error(err); - fail('should not call next'); - }); - server = parseServer.server; - server.on('connection', connection => { - const key = `${connection.remoteAddress}:${connection.remotePort}`; - openConnections[key] = connection; - connection.on('close', () => { - delete openConnections[key]; - }); - }); - } catch (error) { - reject(error); - } +const reconfigureServer = async (changedConfiguration = {}) => { + if (server) { + await new Promise(resolve => server.close(resolve)); + server = undefined; + return reconfigureServer(changedConfiguration); + } + let parseServer = undefined; + didChangeConfiguration = Object.keys(changedConfiguration).length !== 0; + const newConfiguration = Object.assign({}, defaultConfiguration, changedConfiguration, { + mountPath: '/1', + port, + }); + cache.clear(); + parseServer = await ParseServer.start(newConfiguration); + Parse.CoreManager.setRESTController(RESTController); + parseServer.expressApp.use('/1', err => { + console.error(err); + fail('should not call next'); + }); + server = parseServer.server; + server.on('connection', connection => { + const key = `${connection.remoteAddress}:${connection.remotePort}`; + openConnections[key] = connection; + connection.on('close', () => { + delete openConnections[key]; + }); }); }; diff --git a/spec/index.spec.js b/spec/index.spec.js index 837656d1f2..a98d58615f 100644 --- a/spec/index.spec.js +++ b/spec/index.spec.js @@ -295,91 +295,46 @@ describe('server', () => { }); }); - it('can create a parse-server v1', done => { - const parseServer = new ParseServer.default( + it('can create a parse-server v1', async () => { + const parseServer = await new ParseServer.default( Object.assign({}, defaultConfiguration, { appId: 'aTestApp', masterKey: 'aTestMasterKey', serverURL: 'http://localhost:12666/parse', - serverStartComplete: () => { - expect(Parse.applicationId).toEqual('aTestApp'); - const app = express(); - app.use('/parse', parseServer.app); - - const server = app.listen(12666); - const obj = new Parse.Object('AnObject'); - let objId; - obj - .save() - .then(obj => { - objId = obj.id; - const q = new Parse.Query('AnObject'); - return q.first(); - }) - .then(obj => { - expect(obj.id).toEqual(objId); - server.close(async () => { - await reconfigureServer(); - done(); - }); - }) - .catch(() => { - server.close(async () => { - await reconfigureServer(); - done(); - }); - }); - }, }) - ); - }); - - it('can create a parse-server v2', done => { - let objId; - let server; + ).startApp(); + console.log({ parseServer }); + expect(Parse.applicationId).toEqual('aTestApp'); + const app = express(); + app.use('/parse', parseServer); + const server = app.listen(12666); + const obj = new Parse.Object('AnObject'); + await obj.save(); + const query = await new Parse.Query('AnObject').first(); + expect(obj.id).toEqual(query.id); + await new Promise(resolve => server.close(resolve)); + }); + + it('can create a parse-server v2', async () => { const parseServer = ParseServer.ParseServer( Object.assign({}, defaultConfiguration, { appId: 'anOtherTestApp', masterKey: 'anOtherTestMasterKey', serverURL: 'http://localhost:12667/parse', - serverStartComplete: error => { - const promise = error ? Promise.reject(error) : Promise.resolve(); - promise - .then(() => { - expect(Parse.applicationId).toEqual('anOtherTestApp'); - const app = express(); - app.use('/parse', parseServer); - - server = app.listen(12667); - const obj = new Parse.Object('AnObject'); - return obj.save(); - }) - .then(obj => { - objId = obj.id; - const q = new Parse.Query('AnObject'); - return q.first(); - }) - .then(obj => { - expect(obj.id).toEqual(objId); - server.close(async () => { - await reconfigureServer(); - done(); - }); - }) - .catch(error => { - fail(JSON.stringify(error)); - if (server) { - server.close(async () => { - await reconfigureServer(); - done(); - }); - } else { - done(); - } - }); - }, }) ); + + expect(Parse.applicationId).toEqual('anOtherTestApp'); + await parseServer.start(); + const app = express(); + app.use('/parse', parseServer); + + const server = app.listen(12667); + const obj = new Parse.Object('AnObject'); + await obj.save(); + const q = await new Parse.Query('AnObject').first(); + expect(obj.id).toEqual(q.id); + await new Promise(resolve => server.close(resolve)); }); it('has createLiveQueryServer', done => { @@ -551,6 +506,43 @@ describe('server', () => { .catch(done.fail); }); + it('call call start', async () => { + const config = { + appId: 'aTestApp', + masterKey: 'aTestMasterKey', + serverURL: 'http://localhost:12701/parse', + }; + const parseServer = new ParseServer.ParseServer(config); + await parseServer.start(); + expect(Parse.applicationId).toEqual('aTestApp'); + expect(Parse.serverURL).toEqual('http://localhost:12701/parse'); + const app = express(); + app.use('/parse', parseServer); + const server = app.listen(12701); + const testObject = new Parse.Object('TestObject'); + await expectAsync(testObject.save()).toBeResolved(); + await new Promise(resolve => server.close(resolve)); + }); + + it('start is required to mount', async () => { + const config = { + appId: 'aTestApp', + masterKey: 'aTestMasterKey', + serverURL: 'http://localhost:12701/parse', + }; + const parseServer = new ParseServer.ParseServer(config); + expect(Parse.applicationId).toEqual('aTestApp'); + expect(Parse.serverURL).toEqual('http://localhost:12701/parse'); + const app = express(); + app.use('/parse', parseServer); + const server = app.listen(12701); + const testObject = new Parse.Object('TestObject'); + await expectAsync(testObject.save()).toBeRejectedWith( + new Parse.Error(undefined, 'unauthorized') + ); + await new Promise(resolve => server.close(resolve)); + }); + it('should not fail when Google signin is introduced without the optional clientId', done => { const jwt = require('jsonwebtoken'); diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js index d8e3f841dd..7b8fb1cfe0 100644 --- a/src/Options/Definitions.js +++ b/src/Options/Definitions.js @@ -452,10 +452,6 @@ module.exports.ParseServerOptions = { env: 'PARSE_SERVER_SERVER_CLOSE_COMPLETE', help: 'Callback when server has closed', }, - serverStartComplete: { - env: 'PARSE_SERVER_SERVER_START_COMPLETE', - help: 'Callback when server has started', - }, serverURL: { env: 'PARSE_SERVER_URL', help: 'URL to your parse server with http:// or https://.', diff --git a/src/Options/docs.js b/src/Options/docs.js index cbd06ecd25..9473388da3 100644 --- a/src/Options/docs.js +++ b/src/Options/docs.js @@ -83,7 +83,6 @@ * @property {SchemaOptions} schema Defined schema * @property {SecurityOptions} security The security options to identify and report weak security settings. * @property {Function} serverCloseComplete Callback when server has closed - * @property {Function} serverStartComplete Callback when server has started * @property {String} serverURL URL to your parse server with http:// or https://. * @property {Number} sessionLength Session duration, in seconds, defaults to 1 year * @property {Boolean} silent Disables console output diff --git a/src/Options/index.js b/src/Options/index.js index 2592e1e441..baa5016918 100644 --- a/src/Options/index.js +++ b/src/Options/index.js @@ -268,8 +268,6 @@ export interface ParseServerOptions { :ENV: PARSE_SERVER_PLAYGROUND_PATH :DEFAULT: /playground */ playgroundPath: ?string; - /* Callback when server has started */ - serverStartComplete: ?(error: ?Error) => void; /* Defined schema :ENV: PARSE_SERVER_SCHEMA */ diff --git a/src/ParseServer.js b/src/ParseServer.js index e6b30d1918..0365de5363 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -64,64 +64,65 @@ class ParseServer { const { appId = requiredParameter('You must provide an appId!'), masterKey = requiredParameter('You must provide a masterKey!'), - cloud, - security, javascriptKey, serverURL = requiredParameter('You must provide a serverURL!'), - serverStartComplete, - schema, } = options; // Initialize the node client SDK automatically Parse.initialize(appId, javascriptKey || 'unused', masterKey); Parse.serverURL = serverURL; const allControllers = controllers.getControllers(options); - - const { loggerController, databaseController, hooksController } = allControllers; this.config = Config.put(Object.assign({}, options, allControllers)); + logging.setLogger(allControllers.loggerController); + } - logging.setLogger(loggerController); + /** + * Starts the Parse Server to be served as an express. Resolves when parse-server is ready to accept external traffic. + * @returns {Promise} express middleware + */ - // Note: Tests will start to fail if any validation happens after this is called. - databaseController - .performInitialization() - .then(() => hooksController.load()) - .then(async () => { - if (schema) { - await new DefinedSchemas(schema, this.config).execute(); - } - if (serverStartComplete) { - serverStartComplete(); - } - }) - .catch(error => { - if (serverStartComplete) { - serverStartComplete(error); + async startApp() { + try { + if (this.started) { + return this.app; + } + const { databaseController, hooksController, cloud, security, schema } = this.config; + await databaseController.performInitialization(); + await hooksController.load(); + if (schema) { + await new DefinedSchemas(schema, this.config).execute(); + } + if (cloud) { + addParseCloud(); + if (typeof cloud === 'function') { + await Promise.resolve(cloud(Parse)); + } else if (typeof cloud === 'string') { + if (process.env.npm_package_type === 'module') { + await import(path.resolve(process.cwd(), cloud)); + } else { + require(path.resolve(process.cwd(), cloud)); + } } else { - console.error(error); - process.exit(1); + throw "argument 'cloud' must either be a string or a function"; } - }); - - if (cloud) { - addParseCloud(); - if (typeof cloud === 'function') { - cloud(Parse); - } else if (typeof cloud === 'string') { - require(path.resolve(process.cwd(), cloud)); - } else { - throw "argument 'cloud' must either be a string or a function"; } - } - - if (security && security.enableCheck && security.enableCheckLog) { - new CheckRunner(options.security).run(); + if (security && security.enableCheck && security.enableCheckLog) { + new CheckRunner(security).run(); + } + this.started = true; + this.config.started = true; + Config.put(this.config); + return this.app; + } catch (error) { + console.error(error); + throw error; } } get app() { if (!this._app) { this._app = ParseServer.app(this.config); + this._app.start = () => this.startApp(); } return this._app; } @@ -254,7 +255,7 @@ class ParseServer { * @param {Function} callback called when the server has started * @returns {ParseServer} the parse server instance */ - start(options: ParseServerOptions, callback: ?() => void) { + async start(options: ParseServerOptions) { const app = express(); if (options.middleware) { let middleware; @@ -294,7 +295,11 @@ class ParseServer { } } - const server = app.listen(options.port, options.host, callback); + const server = await new Promise(resolve => { + app.listen(options.port, options.host, function () { + resolve(this); + }); + }); this.server = server; if (options.startLiveQueryServer || options.liveQueryServerOptions) { @@ -318,9 +323,10 @@ class ParseServer { * @param {Function} callback called when the server has started * @returns {ParseServer} the parse server instance */ - static start(options: ParseServerOptions, callback: ?() => void) { + static async start(options: ParseServerOptions) { const parseServer = new ParseServer(options); - return parseServer.start(options, callback); + await parseServer.startApp(); + return parseServer.start(options); } /** diff --git a/src/SchemaMigrations/DefinedSchemas.js b/src/SchemaMigrations/DefinedSchemas.js index 5ab737122f..933ed82649 100644 --- a/src/SchemaMigrations/DefinedSchemas.js +++ b/src/SchemaMigrations/DefinedSchemas.js @@ -7,6 +7,8 @@ import { internalCreateSchema, internalUpdateSchema } from '../Routers/SchemasRo import { defaultColumns, systemClasses } from '../Controllers/SchemaController'; import { ParseServerOptions } from '../Options'; import * as Migrations from './Migrations'; +import Auth from '../Auth'; +import rest from '../rest'; export class DefinedSchemas { config: ParseServerOptions; @@ -96,9 +98,9 @@ export class DefinedSchemas { }, 20000); } - // Hack to force session schema to be created await this.createDeleteSession(); - this.allCloudSchemas = await Parse.Schema.all(); + const schemaController = await this.config.database.loadSchema(); + this.allCloudSchemas = await schemaController.getAllClasses(); clearTimeout(timeout); await Promise.all(this.localSchemas.map(async localSchema => this.saveOrUpdate(localSchema))); @@ -171,9 +173,8 @@ export class DefinedSchemas { // Create a fake session since Parse do not create the _Session until // a session is created async createDeleteSession() { - const session = new Parse.Session(); - await session.save(null, { useMasterKey: true }); - await session.destroy({ useMasterKey: true }); + const { response } = await rest.create(this.config, Auth.master(this.config), '_Session', {}); + await rest.del(this.config, Auth.master(this.config), '_Session', response.objectId); } async saveOrUpdate(localSchema: Migrations.JSONSchema) { diff --git a/src/middlewares.js b/src/middlewares.js index 37acf46821..b688cb3078 100644 --- a/src/middlewares.js +++ b/src/middlewares.js @@ -157,9 +157,14 @@ export function handleParseHeaders(req, res, next) { } const clientIp = getClientIp(req); + const config = Config.get(info.appId, mount); + + if (!config.started) { + return invalidRequest(req, res); + } info.app = AppCache.get(info.appId); - req.config = Config.get(info.appId, mount); + req.config = config; req.config.headers = req.headers || {}; req.config.ip = clientIp; req.info = info; From 0505f837573dbdaecb82f7789084898358f01f2a Mon Sep 17 00:00:00 2001 From: dblythy Date: Fri, 14 Oct 2022 12:19:51 +1100 Subject: [PATCH 002/104] Update DefinedSchemas.js --- src/SchemaMigrations/DefinedSchemas.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SchemaMigrations/DefinedSchemas.js b/src/SchemaMigrations/DefinedSchemas.js index 933ed82649..c3a9baab2e 100644 --- a/src/SchemaMigrations/DefinedSchemas.js +++ b/src/SchemaMigrations/DefinedSchemas.js @@ -99,6 +99,7 @@ export class DefinedSchemas { } await this.createDeleteSession(); + // @flow-disable-next-line const schemaController = await this.config.database.loadSchema(); this.allCloudSchemas = await schemaController.getAllClasses(); clearTimeout(timeout); From b7e9d747929abee02192b3259cf7b81e3ca58e2a Mon Sep 17 00:00:00 2001 From: dblythy Date: Fri, 14 Oct 2022 12:39:45 +1100 Subject: [PATCH 003/104] add state --- .babelrc | 3 ++- spec/index.spec.js | 4 ++++ src/ParseServer.js | 12 ++++++++---- src/middlewares.js | 3 +-- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/.babelrc b/.babelrc index 9151969bde..a199154b82 100644 --- a/.babelrc +++ b/.babelrc @@ -7,7 +7,8 @@ ["@babel/preset-env", { "targets": { "node": "12" - } + }, + "exclude": ["proposal-dynamic-import"] }] ], "sourceMaps": "inline" diff --git a/spec/index.spec.js b/spec/index.spec.js index a98d58615f..47e01016a5 100644 --- a/spec/index.spec.js +++ b/spec/index.spec.js @@ -540,6 +540,10 @@ describe('server', () => { await expectAsync(testObject.save()).toBeRejectedWith( new Parse.Error(undefined, 'unauthorized') ); + const health = await request({ + url: 'http://localhost:12701/parse/health', + }).then(res => res.data); + expect(health.status).toBe('initialized'); await new Promise(resolve => server.close(resolve)); }); diff --git a/src/ParseServer.js b/src/ParseServer.js index 0365de5363..ed8428e3c0 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -72,6 +72,7 @@ class ParseServer { Parse.serverURL = serverURL; const allControllers = controllers.getControllers(options); + options.state = 'initialized'; this.config = Config.put(Object.assign({}, options, allControllers)); logging.setLogger(allControllers.loggerController); } @@ -83,9 +84,12 @@ class ParseServer { async startApp() { try { - if (this.started) { + if (this.state === 'ok') { return this.app; } + this.state = 'starting'; + this.config.state = 'starting'; + Config.put(this.config); const { databaseController, hooksController, cloud, security, schema } = this.config; await databaseController.performInitialization(); await hooksController.load(); @@ -109,8 +113,8 @@ class ParseServer { if (security && security.enableCheck && security.enableCheckLog) { new CheckRunner(security).run(); } - this.started = true; - this.config.started = true; + this.state = 'ok'; + this.config.state = 'ok'; Config.put(this.config); return this.app; } catch (error) { @@ -169,7 +173,7 @@ class ParseServer { api.use('/health', function (req, res) { res.json({ - status: 'ok', + status: options.state, }); }); diff --git a/src/middlewares.js b/src/middlewares.js index b688cb3078..b127bd4e7c 100644 --- a/src/middlewares.js +++ b/src/middlewares.js @@ -158,8 +158,7 @@ export function handleParseHeaders(req, res, next) { const clientIp = getClientIp(req); const config = Config.get(info.appId, mount); - - if (!config.started) { + if (config.state !== 'ok') { return invalidRequest(req, res); } From 3134010409b55697bac6e31c6361546c17c10e29 Mon Sep 17 00:00:00 2001 From: dblythy Date: Fri, 14 Oct 2022 12:45:45 +1100 Subject: [PATCH 004/104] Update index.spec.js --- spec/index.spec.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/spec/index.spec.js b/spec/index.spec.js index 47e01016a5..5a95c9f6e6 100644 --- a/spec/index.spec.js +++ b/spec/index.spec.js @@ -547,6 +547,31 @@ describe('server', () => { await new Promise(resolve => server.close(resolve)); }); + it('can get starting state', async () => { + const parseServer = new ParseServer.ParseServer({ + appId: 'test2', + masterKey: 'abc', + serverURL: 'http://localhost:12668/parse', + silent: true, + async cloud() { + await new Promise(resolve => setTimeout(resolve, 1000)); + Parse.Cloud.beforeSave('Test', () => { + throw 'Cannot save.'; + }); + }, + }); + const express = require('express'); + const app = express(); + app.use('/parse', parseServer); + const server = app.listen(12668); + parseServer.start(); + const health = await request({ + url: 'http://localhost:12668/parse/health', + }).then(res => res.data); + expect(health.status).toBe('starting'); + await new Promise(resolve => server.close(resolve)); + }); + it('should not fail when Google signin is introduced without the optional clientId', done => { const jwt = require('jsonwebtoken'); From aefbeefe4bd2087133bbdd8160669212b85c670b Mon Sep 17 00:00:00 2001 From: dblythy Date: Fri, 14 Oct 2022 12:46:13 +1100 Subject: [PATCH 005/104] Update index.spec.js --- spec/index.spec.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/spec/index.spec.js b/spec/index.spec.js index 5a95c9f6e6..17597b7247 100644 --- a/spec/index.spec.js +++ b/spec/index.spec.js @@ -554,10 +554,7 @@ describe('server', () => { serverURL: 'http://localhost:12668/parse', silent: true, async cloud() { - await new Promise(resolve => setTimeout(resolve, 1000)); - Parse.Cloud.beforeSave('Test', () => { - throw 'Cannot save.'; - }); + await new Promise(resolve => setTimeout(resolve, 2000)); }, }); const express = require('express'); From 81413a495bafdd1384a72b5aab20aedee98496b1 Mon Sep 17 00:00:00 2001 From: dblythy Date: Fri, 14 Oct 2022 12:46:56 +1100 Subject: [PATCH 006/104] remove silent --- spec/CloudCode.spec.js | 1 - spec/index.spec.js | 1 - 2 files changed, 2 deletions(-) diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index e33e63ff27..ee60a44594 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -60,7 +60,6 @@ describe('Cloud Code', () => { appId: 'test2', masterKey: 'abc', serverURL: 'http://localhost:12668/parse', - silent: true, async cloud() { await new Promise(resolve => setTimeout(resolve, 1000)); Parse.Cloud.beforeSave('Test', () => { diff --git a/spec/index.spec.js b/spec/index.spec.js index 17597b7247..f23e1ddc42 100644 --- a/spec/index.spec.js +++ b/spec/index.spec.js @@ -552,7 +552,6 @@ describe('server', () => { appId: 'test2', masterKey: 'abc', serverURL: 'http://localhost:12668/parse', - silent: true, async cloud() { await new Promise(resolve => setTimeout(resolve, 2000)); }, From b5965a5bab0d7aa4125a08d8c93e0af34e0cc002 Mon Sep 17 00:00:00 2001 From: dblythy Date: Fri, 14 Oct 2022 12:54:49 +1100 Subject: [PATCH 007/104] fix tests --- src/cli/parse-server.js | 4 ++-- src/middlewares.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cli/parse-server.js b/src/cli/parse-server.js index 4ee9dc4c03..8f97298d44 100755 --- a/src/cli/parse-server.js +++ b/src/cli/parse-server.js @@ -68,12 +68,12 @@ runner({ cluster.fork(); }); } else { - ParseServer.start(options, () => { + ParseServer.start(options).then(() => { printSuccessMessage(); }); } } else { - ParseServer.start(options, () => { + ParseServer.start(options).then(() => { logOptions(); console.log(''); printSuccessMessage(); diff --git a/src/middlewares.js b/src/middlewares.js index b127bd4e7c..2fb4f38e1e 100644 --- a/src/middlewares.js +++ b/src/middlewares.js @@ -158,7 +158,7 @@ export function handleParseHeaders(req, res, next) { const clientIp = getClientIp(req); const config = Config.get(info.appId, mount); - if (config.state !== 'ok') { + if (config.state && config.state !== 'ok') { return invalidRequest(req, res); } From 52d5c899c2c3c6db06acdfee327bb88ac3656112 Mon Sep 17 00:00:00 2001 From: dblythy Date: Fri, 14 Oct 2022 13:49:59 +1100 Subject: [PATCH 008/104] Update helper.js --- spec/helper.js | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/helper.js b/spec/helper.js index 8c9abd2c39..7f57a10928 100644 --- a/spec/helper.js +++ b/spec/helper.js @@ -175,6 +175,7 @@ const reconfigureServer = async (changedConfiguration = {}) => { delete openConnections[key]; }); }); + return parseServer; }; // Set up a Parse client to talk to our test API server From 12f788929b8f78b2953568a1dc4760b3e3f0f896 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 16 Oct 2022 14:52:19 +1100 Subject: [PATCH 009/104] Update ParseServer.js --- src/ParseServer.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ParseServer.js b/src/ParseServer.js index ed8428e3c0..926f1917c2 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -329,7 +329,6 @@ class ParseServer { */ static async start(options: ParseServerOptions) { const parseServer = new ParseServer(options); - await parseServer.startApp(); return parseServer.start(options); } From 4284b8d142bf96587bfb67bb82d450b99e1db074 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 16 Oct 2022 15:43:16 +1100 Subject: [PATCH 010/104] Update ParseServer.js --- src/ParseServer.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/ParseServer.js b/src/ParseServer.js index 926f1917c2..034b5c82d5 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -84,10 +84,9 @@ class ParseServer { async startApp() { try { - if (this.state === 'ok') { + if (this.config.state === 'ok') { return this.app; } - this.state = 'starting'; this.config.state = 'starting'; Config.put(this.config); const { databaseController, hooksController, cloud, security, schema } = this.config; @@ -113,12 +112,12 @@ class ParseServer { if (security && security.enableCheck && security.enableCheckLog) { new CheckRunner(security).run(); } - this.state = 'ok'; this.config.state = 'ok'; Config.put(this.config); return this.app; } catch (error) { console.error(error); + this.config.state = 'error'; throw error; } } @@ -260,6 +259,7 @@ class ParseServer { * @returns {ParseServer} the parse server instance */ async start(options: ParseServerOptions) { + await this.startApp(); const app = express(); if (options.middleware) { let middleware; @@ -270,7 +270,6 @@ class ParseServer { } app.use(middleware); } - app.use(options.mountPath, this.app); if (options.mountGraphQL === true || options.mountPlayground === true) { From ac4ee2b6e45e28b814ae79bd1dc4c3db3d8f614e Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 16 Oct 2022 16:20:46 +1100 Subject: [PATCH 011/104] Update ParseServer.js --- src/ParseServer.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ParseServer.js b/src/ParseServer.js index 034b5c82d5..f0d2145657 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -259,7 +259,11 @@ class ParseServer { * @returns {ParseServer} the parse server instance */ async start(options: ParseServerOptions) { - await this.startApp(); + try { + await this.startApp(); + } catch (e) { + console.error('Error on ParseServer.start: ', e); + } const app = express(); if (options.middleware) { let middleware; From 315bbf13c4947de39af7e1fb22e69b725841363f Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 16 Oct 2022 16:28:25 +1100 Subject: [PATCH 012/104] Update middlewares.js --- src/middlewares.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/middlewares.js b/src/middlewares.js index 2fb4f38e1e..99bdde1c6b 100644 --- a/src/middlewares.js +++ b/src/middlewares.js @@ -159,7 +159,9 @@ export function handleParseHeaders(req, res, next) { const clientIp = getClientIp(req); const config = Config.get(info.appId, mount); if (config.state && config.state !== 'ok') { - return invalidRequest(req, res); + res.status(400); + res.json({ code: Parse.Error.INTERNAL_SERVER_ERROR, error: `Invalid server state: ${config.state}` }); + return; } info.app = AppCache.get(info.appId); From 2d27b7bc1d8da96fc2a3d094a2c746df2ef73ead Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 16 Oct 2022 16:57:25 +1100 Subject: [PATCH 013/104] add state --- spec/helper.js | 9 ++++++--- spec/index.spec.js | 2 +- src/ParseServer.js | 4 +++- src/middlewares.js | 7 +++++-- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/spec/helper.js b/spec/helper.js index 7f57a10928..987b685ad0 100644 --- a/spec/helper.js +++ b/spec/helper.js @@ -154,20 +154,23 @@ const reconfigureServer = async (changedConfiguration = {}) => { server = undefined; return reconfigureServer(changedConfiguration); } - let parseServer = undefined; didChangeConfiguration = Object.keys(changedConfiguration).length !== 0; const newConfiguration = Object.assign({}, defaultConfiguration, changedConfiguration, { mountPath: '/1', port, }); cache.clear(); - parseServer = await ParseServer.start(newConfiguration); + const { parseServer, error } = await ParseServer.start(newConfiguration); + server = parseServer.server; + if (error) { + throw error; + } + Parse.CoreManager.setRESTController(RESTController); parseServer.expressApp.use('/1', err => { console.error(err); fail('should not call next'); }); - server = parseServer.server; server.on('connection', connection => { const key = `${connection.remoteAddress}:${connection.remotePort}`; openConnections[key] = connection; diff --git a/spec/index.spec.js b/spec/index.spec.js index f23e1ddc42..f0835acb4c 100644 --- a/spec/index.spec.js +++ b/spec/index.spec.js @@ -85,7 +85,7 @@ describe('server', () => { expect(response.status).toEqual(500); const body = response.data; expect(body.code).toEqual(1); - expect(body.message).toEqual('Internal server error.'); + expect(body.message).toEqual('Invalid server state: error'); reconfigureServer().then(done, done); }); }); diff --git a/src/ParseServer.js b/src/ParseServer.js index f0d2145657..823ccb30b2 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -259,10 +259,12 @@ class ParseServer { * @returns {ParseServer} the parse server instance */ async start(options: ParseServerOptions) { + let error = null; try { await this.startApp(); } catch (e) { console.error('Error on ParseServer.start: ', e); + error = e; } const app = express(); if (options.middleware) { @@ -321,7 +323,7 @@ class ParseServer { configureListeners(this); } this.expressApp = app; - return this; + return { parseServer: this, error }; } /** diff --git a/src/middlewares.js b/src/middlewares.js index 99bdde1c6b..cc99b89d51 100644 --- a/src/middlewares.js +++ b/src/middlewares.js @@ -159,8 +159,11 @@ export function handleParseHeaders(req, res, next) { const clientIp = getClientIp(req); const config = Config.get(info.appId, mount); if (config.state && config.state !== 'ok') { - res.status(400); - res.json({ code: Parse.Error.INTERNAL_SERVER_ERROR, error: `Invalid server state: ${config.state}` }); + res.status(500); + res.json({ + code: Parse.Error.INTERNAL_SERVER_ERROR, + message: `Invalid server state: ${config.state}`, + }); return; } From 4ba3d688235a9816a76535fbccaf5a04aa1cfe77 Mon Sep 17 00:00:00 2001 From: dblythy Date: Tue, 8 Nov 2022 13:52:56 +1100 Subject: [PATCH 014/104] refactor --- spec/helper.js | 8 ++++---- spec/index.spec.js | 4 ++-- src/ParseServer.js | 5 ++--- src/middlewares.js | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/spec/helper.js b/spec/helper.js index 987b685ad0..41d361382d 100644 --- a/spec/helper.js +++ b/spec/helper.js @@ -160,9 +160,8 @@ const reconfigureServer = async (changedConfiguration = {}) => { port, }); cache.clear(); - const { parseServer, error } = await ParseServer.start(newConfiguration); - server = parseServer.server; - if (error) { + const parseServer = await ParseServer.start(newConfiguration); + if (parseServer.startupError) { throw error; } @@ -171,6 +170,7 @@ const reconfigureServer = async (changedConfiguration = {}) => { console.error(err); fail('should not call next'); }); + server = parseServer.server; server.on('connection', connection => { const key = `${connection.remoteAddress}:${connection.remotePort}`; openConnections[key] = connection; @@ -178,7 +178,7 @@ const reconfigureServer = async (changedConfiguration = {}) => { delete openConnections[key]; }); }); - return parseServer; + return server; }; // Set up a Parse client to talk to our test API server diff --git a/spec/index.spec.js b/spec/index.spec.js index f0835acb4c..f4362e063d 100644 --- a/spec/index.spec.js +++ b/spec/index.spec.js @@ -85,7 +85,7 @@ describe('server', () => { expect(response.status).toEqual(500); const body = response.data; expect(body.code).toEqual(1); - expect(body.message).toEqual('Invalid server state: error'); + expect(body.error).toEqual('Invalid server state: error'); reconfigureServer().then(done, done); }); }); @@ -538,7 +538,7 @@ describe('server', () => { const server = app.listen(12701); const testObject = new Parse.Object('TestObject'); await expectAsync(testObject.save()).toBeRejectedWith( - new Parse.Error(undefined, 'unauthorized') + new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Invalid server state: initialized') ); const health = await request({ url: 'http://localhost:12701/parse/health', diff --git a/src/ParseServer.js b/src/ParseServer.js index bf0ea2ccc4..962ab702e7 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -259,12 +259,11 @@ class ParseServer { * @returns {ParseServer} the parse server instance */ async start(options: ParseServerOptions) { - let error = null; try { await this.startApp(); } catch (e) { console.error('Error on ParseServer.start: ', e); - error = e; + this.startupError = e; } const app = express(); if (options.middleware) { @@ -323,7 +322,7 @@ class ParseServer { configureListeners(this); } this.expressApp = app; - return { parseServer: this, error }; + return this; } /** diff --git a/src/middlewares.js b/src/middlewares.js index cc99b89d51..85d61d8164 100644 --- a/src/middlewares.js +++ b/src/middlewares.js @@ -162,7 +162,7 @@ export function handleParseHeaders(req, res, next) { res.status(500); res.json({ code: Parse.Error.INTERNAL_SERVER_ERROR, - message: `Invalid server state: ${config.state}`, + error: `Invalid server state: ${config.state}`, }); return; } From 64f6eae0a14c87dc8bf114c84cda54d6ee75e5f2 Mon Sep 17 00:00:00 2001 From: dblythy Date: Tue, 8 Nov 2022 13:55:21 +1100 Subject: [PATCH 015/104] Update helper.js --- spec/helper.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/helper.js b/spec/helper.js index 41d361382d..0be3924e85 100644 --- a/spec/helper.js +++ b/spec/helper.js @@ -162,7 +162,7 @@ const reconfigureServer = async (changedConfiguration = {}) => { cache.clear(); const parseServer = await ParseServer.start(newConfiguration); if (parseServer.startupError) { - throw error; + throw parseServer.startupError; } Parse.CoreManager.setRESTController(RESTController); From c59234544bf9098b2fe23ec353ba9df1c77e3ed6 Mon Sep 17 00:00:00 2001 From: dblythy Date: Tue, 8 Nov 2022 14:08:23 +1100 Subject: [PATCH 016/104] Update helper.js --- spec/helper.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/helper.js b/spec/helper.js index 0be3924e85..ff8698854c 100644 --- a/spec/helper.js +++ b/spec/helper.js @@ -178,7 +178,7 @@ const reconfigureServer = async (changedConfiguration = {}) => { delete openConnections[key]; }); }); - return server; + return parseServer; }; // Set up a Parse client to talk to our test API server From 25d1180adc2283d35a154710051262a0069bbe9e Mon Sep 17 00:00:00 2001 From: dblythy Date: Tue, 8 Nov 2022 14:22:43 +1100 Subject: [PATCH 017/104] tests --- spec/helper.js | 2 +- spec/index.spec.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/helper.js b/spec/helper.js index ff8698854c..832776b51f 100644 --- a/spec/helper.js +++ b/spec/helper.js @@ -161,6 +161,7 @@ const reconfigureServer = async (changedConfiguration = {}) => { }); cache.clear(); const parseServer = await ParseServer.start(newConfiguration); + server = parseServer.server; if (parseServer.startupError) { throw parseServer.startupError; } @@ -170,7 +171,6 @@ const reconfigureServer = async (changedConfiguration = {}) => { console.error(err); fail('should not call next'); }); - server = parseServer.server; server.on('connection', connection => { const key = `${connection.remoteAddress}:${connection.remotePort}`; openConnections[key] = connection; diff --git a/spec/index.spec.js b/spec/index.spec.js index f4362e063d..bcc4d2e2b9 100644 --- a/spec/index.spec.js +++ b/spec/index.spec.js @@ -303,7 +303,6 @@ describe('server', () => { serverURL: 'http://localhost:12666/parse', }) ).startApp(); - console.log({ parseServer }); expect(Parse.applicationId).toEqual('aTestApp'); const app = express(); app.use('/parse', parseServer); From 72c7b56c73afe674d4d02f9ece4100a83c0b5248 Mon Sep 17 00:00:00 2001 From: dblythy Date: Tue, 8 Nov 2022 14:54:05 +1100 Subject: [PATCH 018/104] prettier --- spec/helper.js | 11 +++++++---- src/ParseServer.js | 14 ++++++++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/spec/helper.js b/spec/helper.js index 832776b51f..53f076687e 100644 --- a/spec/helper.js +++ b/spec/helper.js @@ -160,10 +160,13 @@ const reconfigureServer = async (changedConfiguration = {}) => { port, }); cache.clear(); - const parseServer = await ParseServer.start(newConfiguration); - server = parseServer.server; - if (parseServer.startupError) { - throw parseServer.startupError; + let parseServer; + try { + parseServer = await ParseServer.start(newConfiguration); + server = parseServer.server; + } catch (e) { + server = parseServer.server; + throw e; } Parse.CoreManager.setRESTController(RESTController); diff --git a/src/ParseServer.js b/src/ParseServer.js index 962ab702e7..9a483b1706 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -90,7 +90,13 @@ class ParseServer { this.config.state = 'starting'; Config.put(this.config); const { databaseController, hooksController, cloud, security, schema } = this.config; - await databaseController.performInitialization(); + try { + await databaseController.performInitialization(); + } catch (e) { + if (e.code !== Parse.Error.DUPLICATE_VALUE) { + throw e; + } + } await hooksController.load(); if (schema) { await new DefinedSchemas(schema, this.config).execute(); @@ -259,11 +265,12 @@ class ParseServer { * @returns {ParseServer} the parse server instance */ async start(options: ParseServerOptions) { + let error = null; try { await this.startApp(); } catch (e) { console.error('Error on ParseServer.start: ', e); - this.startupError = e; + error = e; } const app = express(); if (options.middleware) { @@ -322,6 +329,9 @@ class ParseServer { configureListeners(this); } this.expressApp = app; + if (error) { + throw error; + } return this; } From 73b0eb9b8f265c954127fa275be9604c39768187 Mon Sep 17 00:00:00 2001 From: dblythy Date: Tue, 8 Nov 2022 15:07:47 +1100 Subject: [PATCH 019/104] tests --- spec/ParseLiveQueryServer.spec.js | 4 ++-- spec/helper.js | 11 ++++------- src/ParseServer.js | 5 +---- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/spec/ParseLiveQueryServer.spec.js b/spec/ParseLiveQueryServer.spec.js index 587b2ace87..6fcdb16553 100644 --- a/spec/ParseLiveQueryServer.spec.js +++ b/spec/ParseLiveQueryServer.spec.js @@ -116,7 +116,7 @@ describe('ParseLiveQueryServer', function () { describe_only_db('mongo')('initialization', () => { it('can be initialized through ParseServer without liveQueryServerOptions', async () => { - const parseServer = await ParseServer.start({ + const { parseServer } = await ParseServer.start({ appId: 'hello', masterKey: 'world', port: 22345, @@ -133,7 +133,7 @@ describe('ParseLiveQueryServer', function () { }); it('can be initialized through ParseServer with liveQueryServerOptions', async () => { - const parseServer = await ParseServer.start({ + const { parseServer } = await ParseServer.start({ appId: 'hello', masterKey: 'world', port: 22346, diff --git a/spec/helper.js b/spec/helper.js index 53f076687e..987b685ad0 100644 --- a/spec/helper.js +++ b/spec/helper.js @@ -160,13 +160,10 @@ const reconfigureServer = async (changedConfiguration = {}) => { port, }); cache.clear(); - let parseServer; - try { - parseServer = await ParseServer.start(newConfiguration); - server = parseServer.server; - } catch (e) { - server = parseServer.server; - throw e; + const { parseServer, error } = await ParseServer.start(newConfiguration); + server = parseServer.server; + if (error) { + throw error; } Parse.CoreManager.setRESTController(RESTController); diff --git a/src/ParseServer.js b/src/ParseServer.js index 9a483b1706..eed52824d1 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -329,10 +329,7 @@ class ParseServer { configureListeners(this); } this.expressApp = app; - if (error) { - throw error; - } - return this; + return { parseServer: this, error }; } /** From fc2473b79adf6024e454e487561630b7d1ba69cf Mon Sep 17 00:00:00 2001 From: dblythy Date: Tue, 8 Nov 2022 15:32:31 +1100 Subject: [PATCH 020/104] tests --- spec/ParseLiveQueryServer.spec.js | 4 ++-- spec/helper.js | 6 +++--- spec/support/FailingServer.js | 27 ++++++++++++++++----------- src/ParseServer.js | 5 ++--- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/spec/ParseLiveQueryServer.spec.js b/spec/ParseLiveQueryServer.spec.js index 6fcdb16553..587b2ace87 100644 --- a/spec/ParseLiveQueryServer.spec.js +++ b/spec/ParseLiveQueryServer.spec.js @@ -116,7 +116,7 @@ describe('ParseLiveQueryServer', function () { describe_only_db('mongo')('initialization', () => { it('can be initialized through ParseServer without liveQueryServerOptions', async () => { - const { parseServer } = await ParseServer.start({ + const parseServer = await ParseServer.start({ appId: 'hello', masterKey: 'world', port: 22345, @@ -133,7 +133,7 @@ describe('ParseLiveQueryServer', function () { }); it('can be initialized through ParseServer with liveQueryServerOptions', async () => { - const { parseServer } = await ParseServer.start({ + const parseServer = await ParseServer.start({ appId: 'hello', masterKey: 'world', port: 22346, diff --git a/spec/helper.js b/spec/helper.js index 987b685ad0..832776b51f 100644 --- a/spec/helper.js +++ b/spec/helper.js @@ -160,10 +160,10 @@ const reconfigureServer = async (changedConfiguration = {}) => { port, }); cache.clear(); - const { parseServer, error } = await ParseServer.start(newConfiguration); + const parseServer = await ParseServer.start(newConfiguration); server = parseServer.server; - if (error) { - throw error; + if (parseServer.startupError) { + throw parseServer.startupError; } Parse.CoreManager.setRESTController(RESTController); diff --git a/spec/support/FailingServer.js b/spec/support/FailingServer.js index 2123961f65..8ad9234631 100755 --- a/spec/support/FailingServer.js +++ b/spec/support/FailingServer.js @@ -6,14 +6,19 @@ const ParseServer = require('../../lib/index').ParseServer; const databaseURI = 'mongodb://doesnotexist:27017/parseServerMongoAdapterTestDatabase'; -ParseServer.start({ - appId: 'test', - masterKey: 'test', - databaseAdapter: new MongoStorageAdapter({ - uri: databaseURI, - mongoOptions: { - serverSelectionTimeoutMS: 2000, - }, - }), - filesAdapter: new GridFSBucketAdapter(databaseURI), -}); +(async () => { + const parseServer = await ParseServer.start({ + appId: 'test', + masterKey: 'test', + databaseAdapter: new MongoStorageAdapter({ + uri: databaseURI, + mongoOptions: { + serverSelectionTimeoutMS: 2000, + }, + }), + filesAdapter: new GridFSBucketAdapter(databaseURI), + }); + if (parseServer.startupError) { + throw parseServer.startupError; + } +})(); diff --git a/src/ParseServer.js b/src/ParseServer.js index eed52824d1..55c3e11e37 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -265,12 +265,11 @@ class ParseServer { * @returns {ParseServer} the parse server instance */ async start(options: ParseServerOptions) { - let error = null; try { await this.startApp(); } catch (e) { console.error('Error on ParseServer.start: ', e); - error = e; + this.startupError = e; } const app = express(); if (options.middleware) { @@ -329,7 +328,7 @@ class ParseServer { configureListeners(this); } this.expressApp = app; - return { parseServer: this, error }; + return this; } /** From 1e72a891c720e94f6ca48e427d8a2bf1136d2edb Mon Sep 17 00:00:00 2001 From: dblythy Date: Tue, 8 Nov 2022 15:50:19 +1100 Subject: [PATCH 021/104] Update ParseServer.spec.js --- spec/ParseServer.spec.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/ParseServer.spec.js b/spec/ParseServer.spec.js index fcb15f643f..d721536260 100644 --- a/spec/ParseServer.spec.js +++ b/spec/ParseServer.spec.js @@ -95,15 +95,17 @@ describe('Server Url Checks', () => { const parseServer = ParseServer.start(newConfiguration); }); - it('does not have unhandled promise rejection in the case of load error', done => { + fit('does not have unhandled promise rejection in the case of load error', done => { const parseServerProcess = spawn(path.resolve(__dirname, './support/FailingServer.js')); let stdout; let stderr; parseServerProcess.stdout.on('data', data => { stdout = data.toString(); + console.log(data.toString()); }); parseServerProcess.stderr.on('data', data => { stderr = data.toString(); + console.log('error: ', data.toString()); }); parseServerProcess.on('close', async code => { expect(code).toEqual(1); From 69466b40765f71694ea5f6ae0386dcd80a24533b Mon Sep 17 00:00:00 2001 From: dblythy Date: Tue, 8 Nov 2022 15:52:41 +1100 Subject: [PATCH 022/104] Update ParseServer.spec.js --- spec/ParseServer.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/ParseServer.spec.js b/spec/ParseServer.spec.js index d721536260..2efb5d38b4 100644 --- a/spec/ParseServer.spec.js +++ b/spec/ParseServer.spec.js @@ -95,7 +95,7 @@ describe('Server Url Checks', () => { const parseServer = ParseServer.start(newConfiguration); }); - fit('does not have unhandled promise rejection in the case of load error', done => { + it('does not have unhandled promise rejection in the case of load error', done => { const parseServerProcess = spawn(path.resolve(__dirname, './support/FailingServer.js')); let stdout; let stderr; From b27f0ad3c30cb1121c2d51729341f9c45069194e Mon Sep 17 00:00:00 2001 From: dblythy Date: Tue, 8 Nov 2022 16:16:48 +1100 Subject: [PATCH 023/104] Update helper.js --- spec/helper.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/spec/helper.js b/spec/helper.js index 832776b51f..4f007893eb 100644 --- a/spec/helper.js +++ b/spec/helper.js @@ -162,10 +162,6 @@ const reconfigureServer = async (changedConfiguration = {}) => { cache.clear(); const parseServer = await ParseServer.start(newConfiguration); server = parseServer.server; - if (parseServer.startupError) { - throw parseServer.startupError; - } - Parse.CoreManager.setRESTController(RESTController); parseServer.expressApp.use('/1', err => { console.error(err); @@ -178,6 +174,9 @@ const reconfigureServer = async (changedConfiguration = {}) => { delete openConnections[key]; }); }); + if (parseServer.startupError) { + throw parseServer.startupError; + } return parseServer; }; From 48cb44f8d3a0b92452078e72d066e1602717ddac Mon Sep 17 00:00:00 2001 From: dblythy Date: Tue, 8 Nov 2022 16:33:53 +1100 Subject: [PATCH 024/104] failing server --- spec/ParseServer.spec.js | 2 -- spec/support/FailingServer.js | 6 ++---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/spec/ParseServer.spec.js b/spec/ParseServer.spec.js index 2efb5d38b4..fcb15f643f 100644 --- a/spec/ParseServer.spec.js +++ b/spec/ParseServer.spec.js @@ -101,11 +101,9 @@ describe('Server Url Checks', () => { let stderr; parseServerProcess.stdout.on('data', data => { stdout = data.toString(); - console.log(data.toString()); }); parseServerProcess.stderr.on('data', data => { stderr = data.toString(); - console.log('error: ', data.toString()); }); parseServerProcess.on('close', async code => { expect(code).toEqual(1); diff --git a/spec/support/FailingServer.js b/spec/support/FailingServer.js index 8ad9234631..4f3f72da2e 100755 --- a/spec/support/FailingServer.js +++ b/spec/support/FailingServer.js @@ -7,7 +7,7 @@ const ParseServer = require('../../lib/index').ParseServer; const databaseURI = 'mongodb://doesnotexist:27017/parseServerMongoAdapterTestDatabase'; (async () => { - const parseServer = await ParseServer.start({ + await ParseServer.start({ appId: 'test', masterKey: 'test', databaseAdapter: new MongoStorageAdapter({ @@ -18,7 +18,5 @@ const databaseURI = 'mongodb://doesnotexist:27017/parseServerMongoAdapterTestDat }), filesAdapter: new GridFSBucketAdapter(databaseURI), }); - if (parseServer.startupError) { - throw parseServer.startupError; - } + process.exit(1); })(); From f6331fc19fb747640d8268561b847449154f22dd Mon Sep 17 00:00:00 2001 From: dblythy Date: Tue, 8 Nov 2022 18:56:20 +1100 Subject: [PATCH 025/104] refactor --- spec/CloudCode.spec.js | 8 ++++---- spec/ParseLiveQueryServer.spec.js | 4 ++-- spec/ParseServer.spec.js | 2 +- spec/helper.js | 5 +---- spec/index.spec.js | 12 +++++++----- spec/support/FailingServer.js | 6 +++++- src/ParseServer.js | 20 ++++++++------------ src/cli/parse-server.js | 4 ++-- src/index.js | 4 ++-- 9 files changed, 32 insertions(+), 33 deletions(-) diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index 7a2c536650..b47f73c696 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -55,10 +55,11 @@ describe('Cloud Code', () => { }); it('should wait for cloud code to load', async () => { + await reconfigureServer({ appId: 'test3' }) const initiated = new Date(); const parseServer = await new ParseServer({ - appId: 'test2', - masterKey: 'abc', + appId: 'test3', + masterKey: 'test', serverURL: 'http://localhost:12668/parse', async cloud() { await new Promise(resolve => setTimeout(resolve, 1000)); @@ -69,9 +70,8 @@ describe('Cloud Code', () => { }).start(); const express = require('express'); const app = express(); - app.use('/parse', parseServer); + app.use('/parse', parseServer.app); const server = app.listen(12668); - const now = new Date(); expect(now.getTime() - initiated.getTime() > 1000).toBeTrue(); await expectAsync(new Parse.Object('Test').save()).toBeRejectedWith( diff --git a/spec/ParseLiveQueryServer.spec.js b/spec/ParseLiveQueryServer.spec.js index 587b2ace87..a566ab96c0 100644 --- a/spec/ParseLiveQueryServer.spec.js +++ b/spec/ParseLiveQueryServer.spec.js @@ -116,7 +116,7 @@ describe('ParseLiveQueryServer', function () { describe_only_db('mongo')('initialization', () => { it('can be initialized through ParseServer without liveQueryServerOptions', async () => { - const parseServer = await ParseServer.start({ + const parseServer = await ParseServer.startApp({ appId: 'hello', masterKey: 'world', port: 22345, @@ -133,7 +133,7 @@ describe('ParseLiveQueryServer', function () { }); it('can be initialized through ParseServer with liveQueryServerOptions', async () => { - const parseServer = await ParseServer.start({ + const parseServer = await ParseServer.startApp({ appId: 'hello', masterKey: 'world', port: 22346, diff --git a/spec/ParseServer.spec.js b/spec/ParseServer.spec.js index fcb15f643f..d78e07a09a 100644 --- a/spec/ParseServer.spec.js +++ b/spec/ParseServer.spec.js @@ -92,7 +92,7 @@ describe('Server Url Checks', () => { close = true; }, }); - const parseServer = ParseServer.start(newConfiguration); + const parseServer = ParseServer.startApp(newConfiguration); }); it('does not have unhandled promise rejection in the case of load error', done => { diff --git a/spec/helper.js b/spec/helper.js index 4f007893eb..100f87cb3e 100644 --- a/spec/helper.js +++ b/spec/helper.js @@ -160,7 +160,7 @@ const reconfigureServer = async (changedConfiguration = {}) => { port, }); cache.clear(); - const parseServer = await ParseServer.start(newConfiguration); + const parseServer = await ParseServer.startApp(newConfiguration); server = parseServer.server; Parse.CoreManager.setRESTController(RESTController); parseServer.expressApp.use('/1', err => { @@ -174,9 +174,6 @@ const reconfigureServer = async (changedConfiguration = {}) => { delete openConnections[key]; }); }); - if (parseServer.startupError) { - throw parseServer.startupError; - } return parseServer; }; diff --git a/spec/index.spec.js b/spec/index.spec.js index bcc4d2e2b9..1eea41225c 100644 --- a/spec/index.spec.js +++ b/spec/index.spec.js @@ -296,16 +296,18 @@ describe('server', () => { }); it('can create a parse-server v1', async () => { - const parseServer = await new ParseServer.default( + await reconfigureServer({ appId: 'aTestApp' }) + const parseServer = new ParseServer.default( Object.assign({}, defaultConfiguration, { appId: 'aTestApp', masterKey: 'aTestMasterKey', serverURL: 'http://localhost:12666/parse', }) - ).startApp(); + ); + await parseServer.start(); expect(Parse.applicationId).toEqual('aTestApp'); const app = express(); - app.use('/parse', parseServer); + app.use('/parse', parseServer.app); const server = app.listen(12666); const obj = new Parse.Object('AnObject'); await obj.save(); @@ -315,6 +317,7 @@ describe('server', () => { }); it('can create a parse-server v2', async () => { + await reconfigureServer({ appId: 'anOtherTestApp' }) const parseServer = ParseServer.ParseServer( Object.assign({}, defaultConfiguration, { appId: 'anOtherTestApp', @@ -326,8 +329,7 @@ describe('server', () => { expect(Parse.applicationId).toEqual('anOtherTestApp'); await parseServer.start(); const app = express(); - app.use('/parse', parseServer); - + app.use('/parse', parseServer.app); const server = app.listen(12667); const obj = new Parse.Object('AnObject'); await obj.save(); diff --git a/spec/support/FailingServer.js b/spec/support/FailingServer.js index 4f3f72da2e..620b10485b 100755 --- a/spec/support/FailingServer.js +++ b/spec/support/FailingServer.js @@ -7,7 +7,8 @@ const ParseServer = require('../../lib/index').ParseServer; const databaseURI = 'mongodb://doesnotexist:27017/parseServerMongoAdapterTestDatabase'; (async () => { - await ParseServer.start({ + try { + await ParseServer.startApp({ appId: 'test', masterKey: 'test', databaseAdapter: new MongoStorageAdapter({ @@ -18,5 +19,8 @@ const databaseURI = 'mongodb://doesnotexist:27017/parseServerMongoAdapterTestDat }), filesAdapter: new GridFSBucketAdapter(databaseURI), }); +} catch (e) { + console.log(e); process.exit(1); + } })(); diff --git a/src/ParseServer.js b/src/ParseServer.js index 55c3e11e37..bed2061868 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -79,13 +79,12 @@ class ParseServer { /** * Starts the Parse Server to be served as an express. Resolves when parse-server is ready to accept external traffic. - * @returns {Promise} express middleware */ - async startApp() { + async start() { try { if (this.config.state === 'ok') { - return this.app; + return this; } this.config.state = 'starting'; Config.put(this.config); @@ -120,7 +119,7 @@ class ParseServer { } this.config.state = 'ok'; Config.put(this.config); - return this.app; + return this; } catch (error) { console.error(error); this.config.state = 'error'; @@ -131,7 +130,6 @@ class ParseServer { get app() { if (!this._app) { this._app = ParseServer.app(this.config); - this._app.start = () => this.startApp(); } return this._app; } @@ -261,15 +259,14 @@ class ParseServer { /** * starts the parse server's express app * @param {ParseServerOptions} options to use to start the server - * @param {Function} callback called when the server has started * @returns {ParseServer} the parse server instance */ - async start(options: ParseServerOptions) { + async startApp(options: ParseServerOptions) { try { - await this.startApp(); + await this.start(); } catch (e) { console.error('Error on ParseServer.start: ', e); - this.startupError = e; + throw e; } const app = express(); if (options.middleware) { @@ -334,12 +331,11 @@ class ParseServer { /** * Creates a new ParseServer and starts it. * @param {ParseServerOptions} options used to start the server - * @param {Function} callback called when the server has started * @returns {ParseServer} the parse server instance */ - static async start(options: ParseServerOptions) { + static async startApp(options: ParseServerOptions) { const parseServer = new ParseServer(options); - return parseServer.start(options); + return parseServer.startApp(options); } /** diff --git a/src/cli/parse-server.js b/src/cli/parse-server.js index 8f97298d44..ee268a920d 100755 --- a/src/cli/parse-server.js +++ b/src/cli/parse-server.js @@ -68,12 +68,12 @@ runner({ cluster.fork(); }); } else { - ParseServer.start(options).then(() => { + ParseServer.startApp(options).then(() => { printSuccessMessage(); }); } } else { - ParseServer.start(options).then(() => { + ParseServer.startApp(options).then(() => { logOptions(); console.log(''); printSuccessMessage(); diff --git a/src/index.js b/src/index.js index bbbdaf545f..684443ce5b 100644 --- a/src/index.js +++ b/src/index.js @@ -16,11 +16,11 @@ import { ParseGraphQLServer } from './GraphQL/ParseGraphQLServer'; // Factory function const _ParseServer = function (options: ParseServerOptions) { const server = new ParseServer(options); - return server.app; + return server; }; // Mount the create liveQueryServer _ParseServer.createLiveQueryServer = ParseServer.createLiveQueryServer; -_ParseServer.start = ParseServer.start; +_ParseServer.startApp = ParseServer.startApp; const S3Adapter = useExternal('S3Adapter', '@parse/s3-files-adapter'); const GCSAdapter = useExternal('GCSAdapter', '@parse/gcs-files-adapter'); From 8dc3615d1ae92468978721e397e715380c36da37 Mon Sep 17 00:00:00 2001 From: dblythy Date: Fri, 18 Nov 2022 11:53:25 +1100 Subject: [PATCH 026/104] fix lint --- spec/CloudCode.spec.js | 2 +- spec/index.spec.js | 4 ++-- spec/support/FailingServer.js | 28 ++++++++++++++-------------- src/ParseServer.js | 16 ++++++++++++++-- 4 files changed, 31 insertions(+), 19 deletions(-) diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index c4b22983e3..e94c5d00da 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -55,7 +55,7 @@ describe('Cloud Code', () => { }); it('should wait for cloud code to load', async () => { - await reconfigureServer({ appId: 'test3' }) + await reconfigureServer({ appId: 'test3' }); const initiated = new Date(); const parseServer = await new ParseServer({ appId: 'test3', diff --git a/spec/index.spec.js b/spec/index.spec.js index ebe8db274e..bfaf3a92d9 100644 --- a/spec/index.spec.js +++ b/spec/index.spec.js @@ -296,7 +296,7 @@ describe('server', () => { }); it('can create a parse-server v1', async () => { - await reconfigureServer({ appId: 'aTestApp' }) + await reconfigureServer({ appId: 'aTestApp' }); const parseServer = new ParseServer.default( Object.assign({}, defaultConfiguration, { appId: 'aTestApp', @@ -317,7 +317,7 @@ describe('server', () => { }); it('can create a parse-server v2', async () => { - await reconfigureServer({ appId: 'anOtherTestApp' }) + await reconfigureServer({ appId: 'anOtherTestApp' }); const parseServer = ParseServer.ParseServer( Object.assign({}, defaultConfiguration, { appId: 'anOtherTestApp', diff --git a/spec/support/FailingServer.js b/spec/support/FailingServer.js index 620b10485b..701e30c2aa 100755 --- a/spec/support/FailingServer.js +++ b/spec/support/FailingServer.js @@ -8,19 +8,19 @@ const databaseURI = 'mongodb://doesnotexist:27017/parseServerMongoAdapterTestDat (async () => { try { - await ParseServer.startApp({ - appId: 'test', - masterKey: 'test', - databaseAdapter: new MongoStorageAdapter({ - uri: databaseURI, - mongoOptions: { - serverSelectionTimeoutMS: 2000, - }, - }), - filesAdapter: new GridFSBucketAdapter(databaseURI), - }); -} catch (e) { - console.log(e); - process.exit(1); + await ParseServer.startApp({ + appId: 'test', + masterKey: 'test', + databaseAdapter: new MongoStorageAdapter({ + uri: databaseURI, + mongoOptions: { + serverSelectionTimeoutMS: 2000, + }, + }), + filesAdapter: new GridFSBucketAdapter(databaseURI), + }); + } catch (e) { + console.log(e); + process.exit(1); } })(); diff --git a/src/ParseServer.js b/src/ParseServer.js index bed2061868..0cbd6b4057 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -88,7 +88,14 @@ class ParseServer { } this.config.state = 'starting'; Config.put(this.config); - const { databaseController, hooksController, cloud, security, schema } = this.config; + const { + databaseController, + hooksController, + cloud, + security, + schema, + cacheAdapter, + } = this.config; try { await databaseController.performInitialization(); } catch (e) { @@ -97,9 +104,14 @@ class ParseServer { } } await hooksController.load(); + const startupPromises = []; if (schema) { - await new DefinedSchemas(schema, this.config).execute(); + startupPromises.push(new DefinedSchemas(schema, this.config).execute()); } + if (cacheAdapter?.connect && typeof cacheAdapter.connect === 'function') { + startupPromises.push(cacheAdapter.connect()); + } + await Promise.all(startupPromises); if (cloud) { addParseCloud(); if (typeof cloud === 'function') { From 89828ed3a5bba736392cafb386212ed364d8736a Mon Sep 17 00:00:00 2001 From: dblythy Date: Fri, 18 Nov 2022 12:30:36 +1100 Subject: [PATCH 027/104] Update CLI.spec.js --- spec/CLI.spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index 540f02abf6..4e9e821083 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -226,7 +226,7 @@ describe('execution', () => { '--masterKey', 'test', '--databaseURI', - 'mongodb://localhost/test', + 'mongodb://127.0.0.1/test', '--port', '1339', ]); @@ -248,7 +248,7 @@ describe('execution', () => { '--masterKey', 'test', '--databaseURI', - 'mongodb://localhost/test', + 'mongodb://127.0.0.1/test', '--port', '1340', '--mountGraphQL', @@ -274,7 +274,7 @@ describe('execution', () => { '--masterKey', 'test', '--databaseURI', - 'mongodb://localhost/test', + 'mongodb://127.0.0.1/test', '--port', '1341', '--mountGraphQL', From 7800b4180388831a6e1e80ced91203f734f15b08 Mon Sep 17 00:00:00 2001 From: dblythy Date: Fri, 18 Nov 2022 13:08:36 +1100 Subject: [PATCH 028/104] Update index.spec.js --- spec/index.spec.js | 45 ++++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/spec/index.spec.js b/spec/index.spec.js index bfaf3a92d9..744323c90a 100644 --- a/spec/index.spec.js +++ b/spec/index.spec.js @@ -61,34 +61,19 @@ describe('server', () => { }); }); - it('fails if database is unreachable', done => { - reconfigureServer({ + it('fails if database is unreachable', async () => { + const server = new ParseServer.default({ + ...defaultConfiguration, databaseAdapter: new MongoStorageAdapter({ uri: 'mongodb://fake:fake@localhost:43605/drew3', mongoOptions: { serverSelectionTimeoutMS: 2000, }, }), - }).catch(() => { - const config = Config.get('test'); - config.schemaCache.clear(); - //Need to use rest api because saving via JS SDK results in fail() not getting called - request({ - method: 'POST', - url: 'http://localhost:8378/1/classes/NewClass', - headers: { - 'X-Parse-Application-Id': 'test', - 'X-Parse-REST-API-Key': 'rest', - }, - body: {}, - }).then(fail, response => { - expect(response.status).toEqual(500); - const body = response.data; - expect(body.code).toEqual(1); - expect(body.error).toEqual('Invalid server state: error'); - reconfigureServer().then(done, done); - }); }); + const error = await server.start().catch(e => e); + expect(`${error}`.includes('MongoServerSelectionError')).toBeTrue(); + await reconfigureServer(); }); describe('mail adapter', () => { @@ -509,7 +494,7 @@ describe('server', () => { .catch(done.fail); }); - it('call call start', async () => { + it('can call start', async () => { const config = { appId: 'aTestApp', masterKey: 'aTestMasterKey', @@ -520,7 +505,7 @@ describe('server', () => { expect(Parse.applicationId).toEqual('aTestApp'); expect(Parse.serverURL).toEqual('http://localhost:12701/parse'); const app = express(); - app.use('/parse', parseServer); + app.use('/parse', parseServer.app); const server = app.listen(12701); const testObject = new Parse.Object('TestObject'); await expectAsync(testObject.save()).toBeResolved(); @@ -537,10 +522,16 @@ describe('server', () => { expect(Parse.applicationId).toEqual('aTestApp'); expect(Parse.serverURL).toEqual('http://localhost:12701/parse'); const app = express(); - app.use('/parse', parseServer); + app.use('/parse', parseServer.app); const server = app.listen(12701); - const testObject = new Parse.Object('TestObject'); - await expectAsync(testObject.save()).toBeRejectedWith( + const response = await request({ + headers: { + 'X-Parse-Application-Id': 'aTestApp', + }, + method: 'POST', + url: 'http://localhost:12701/parse/classes/TestObject', + }).catch(e => new Parse.Error(e.data.code, e.data.error)); + expect(response).toEqual( new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Invalid server state: initialized') ); const health = await request({ @@ -561,7 +552,7 @@ describe('server', () => { }); const express = require('express'); const app = express(); - app.use('/parse', parseServer); + app.use('/parse', parseServer.app); const server = app.listen(12668); parseServer.start(); const health = await request({ From 84c04401cb7dc6e52b0b6cbb73426c08b0a44986 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 10:15:15 +1100 Subject: [PATCH 029/104] Update CLI.spec.js --- spec/CLI.spec.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index 4e9e821083..3815551359 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -219,7 +219,7 @@ describe('execution', () => { } }); - it('shoud start Parse Server', done => { + it('should start Parse Server', done => { childProcess = spawn(binPath, [ '--appId', 'test', @@ -232,6 +232,7 @@ describe('execution', () => { ]); childProcess.stdout.on('data', data => { data = data.toString(); + console.log({data}); if (data.includes('parse-server running on')) { done(); } @@ -241,7 +242,7 @@ describe('execution', () => { }); }); - it('shoud start Parse Server with GraphQL', done => { + it('should start Parse Server with GraphQL', done => { childProcess = spawn(binPath, [ '--appId', 'test', @@ -267,7 +268,7 @@ describe('execution', () => { }); }); - it('shoud start Parse Server with GraphQL and Playground', done => { + it('should start Parse Server with GraphQL and Playground', done => { childProcess = spawn(binPath, [ '--appId', 'test', From c1cd6e0f4acb658066a7f4c32a1787acfdf7db99 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 10:42:38 +1100 Subject: [PATCH 030/104] Update CLI.spec.js --- spec/CLI.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index 3815551359..609a5b4c66 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -226,7 +226,7 @@ describe('execution', () => { '--masterKey', 'test', '--databaseURI', - 'mongodb://127.0.0.1/test', + 'mongodb://127.0.0.1:27017/test', '--port', '1339', ]); From 73391f1facb65a0f1d16d2e263dfe93957f0cfd0 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 14:12:48 +1100 Subject: [PATCH 031/104] tests --- spec/CLI.spec.js | 5 ++--- src/ParseServer.js | 7 ++++++- src/cli/parse-server.js | 8 ++++++++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index 609a5b4c66..9ad8c1c875 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -219,7 +219,7 @@ describe('execution', () => { } }); - it('should start Parse Server', done => { + fit('should start Parse Server', done => { childProcess = spawn(binPath, [ '--appId', 'test', @@ -232,7 +232,6 @@ describe('execution', () => { ]); childProcess.stdout.on('data', data => { data = data.toString(); - console.log({data}); if (data.includes('parse-server running on')) { done(); } @@ -249,7 +248,7 @@ describe('execution', () => { '--masterKey', 'test', '--databaseURI', - 'mongodb://127.0.0.1/test', + 'mongodb://127.0.0.1:27017/test', '--port', '1340', '--mountGraphQL', diff --git a/src/ParseServer.js b/src/ParseServer.js index 0cbd6b4057..ed0b4e9dfa 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -346,8 +346,13 @@ class ParseServer { * @returns {ParseServer} the parse server instance */ static async startApp(options: ParseServerOptions) { + console.log('call start') const parseServer = new ParseServer(options); - return parseServer.startApp(options); + try { + await parseServer.startApp(options); + } catch (err) { + console.log({err}); + } } /** diff --git a/src/cli/parse-server.js b/src/cli/parse-server.js index ee268a920d..aa947d8989 100755 --- a/src/cli/parse-server.js +++ b/src/cli/parse-server.js @@ -68,15 +68,23 @@ runner({ cluster.fork(); }); } else { + console.log('start app 1'); ParseServer.startApp(options).then(() => { printSuccessMessage(); + }).catch(e => { + console.log(e); + throw e; }); } } else { + console.log('start app 2'); ParseServer.startApp(options).then(() => { logOptions(); console.log(''); printSuccessMessage(); + }).catch(e => { + console.log(e); + throw e; }); } From e033ff72e8e270eaf3dd8b6f0afe57dac7693b36 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 14:15:34 +1100 Subject: [PATCH 032/104] test --- spec/CLI.spec.js | 4 ++-- src/ParseServer.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index 9ad8c1c875..ebd7ca88f2 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -205,7 +205,7 @@ describe('LiveQuery definitions', () => { }); }); -describe('execution', () => { +fdescribe('execution', () => { const binPath = path.resolve(__dirname, '../bin/parse-server'); let childProcess; @@ -219,7 +219,7 @@ describe('execution', () => { } }); - fit('should start Parse Server', done => { + it('should start Parse Server', done => { childProcess = spawn(binPath, [ '--appId', 'test', diff --git a/src/ParseServer.js b/src/ParseServer.js index ed0b4e9dfa..2b20d914e7 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -349,7 +349,7 @@ class ParseServer { console.log('call start') const parseServer = new ParseServer(options); try { - await parseServer.startApp(options); + return await parseServer.startApp(options); } catch (err) { console.log({err}); } From f2759e029b5a0f8e7f09c79e93ccaa320023a703 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 14:22:51 +1100 Subject: [PATCH 033/104] Update CLI.spec.js --- spec/CLI.spec.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index ebd7ca88f2..77873f36eb 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -205,7 +205,7 @@ describe('LiveQuery definitions', () => { }); }); -fdescribe('execution', () => { +describe('execution', () => { const binPath = path.resolve(__dirname, '../bin/parse-server'); let childProcess; @@ -232,6 +232,7 @@ fdescribe('execution', () => { ]); childProcess.stdout.on('data', data => { data = data.toString(); + console.log({data}); if (data.includes('parse-server running on')) { done(); } From 72093ed0b5f2365d7637fc34e54f1444a2f6f6e0 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 14:52:06 +1100 Subject: [PATCH 034/104] Update ParseServer.js --- src/ParseServer.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ParseServer.js b/src/ParseServer.js index 2b20d914e7..ba354f474c 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -277,6 +277,7 @@ class ParseServer { try { await this.start(); } catch (e) { + console.log({e}); console.error('Error on ParseServer.start: ', e); throw e; } @@ -317,12 +318,13 @@ class ParseServer { parseGraphQLServer.applyPlayground(app); } } - + console.log('starting server') const server = await new Promise(resolve => { app.listen(options.port, options.host, function () { resolve(this); }); }); + console.log('server started') this.server = server; if (options.startLiveQueryServer || options.liveQueryServerOptions) { @@ -349,7 +351,7 @@ class ParseServer { console.log('call start') const parseServer = new ParseServer(options); try { - return await parseServer.startApp(options); + return parseServer.startApp(options); } catch (err) { console.log({err}); } From 513ca5adae7fe85612decfcd1341f827145050a8 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 15:15:43 +1100 Subject: [PATCH 035/104] tests --- spec/CLI.spec.js | 6 ++++-- src/ParseServer.js | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index 77873f36eb..e1a4d54181 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -27,7 +27,7 @@ const testDefinitions = { }, }; -describe('commander additions', () => { +fdescribe('commander additions', () => { afterEach(done => { commander.options = []; delete commander.arg0; @@ -226,7 +226,7 @@ describe('execution', () => { '--masterKey', 'test', '--databaseURI', - 'mongodb://127.0.0.1:27017/test', + 'mongodb://localhost:27017/test', '--port', '1339', ]); @@ -257,6 +257,7 @@ describe('execution', () => { let output = ''; childProcess.stdout.on('data', data => { data = data.toString(); + console.log({data}); output += data; if (data.includes('GraphQL running on')) { expect(output).toMatch('parse-server running on'); @@ -284,6 +285,7 @@ describe('execution', () => { let output = ''; childProcess.stdout.on('data', data => { data = data.toString(); + console.log({data}); output += data; if (data.includes('Playground running on')) { expect(output).toMatch('GraphQL running on'); diff --git a/src/ParseServer.js b/src/ParseServer.js index ba354f474c..2e64bb21e0 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -83,10 +83,12 @@ class ParseServer { async start() { try { + console.log('b'); if (this.config.state === 'ok') { return this; } this.config.state = 'starting'; + console.log('c'); Config.put(this.config); const { databaseController, @@ -97,12 +99,16 @@ class ParseServer { cacheAdapter, } = this.config; try { + console.log('initialising...'); await databaseController.performInitialization(); + console.log('initialised...'); } catch (e) { + console.log(e); if (e.code !== Parse.Error.DUPLICATE_VALUE) { throw e; } } + console.log('d'); await hooksController.load(); const startupPromises = []; if (schema) { @@ -111,6 +117,7 @@ class ParseServer { if (cacheAdapter?.connect && typeof cacheAdapter.connect === 'function') { startupPromises.push(cacheAdapter.connect()); } + console.log('f'); await Promise.all(startupPromises); if (cloud) { addParseCloud(); @@ -129,6 +136,7 @@ class ParseServer { if (security && security.enableCheck && security.enableCheckLog) { new CheckRunner(security).run(); } + console.log('g'); this.config.state = 'ok'; Config.put(this.config); return this; @@ -274,7 +282,9 @@ class ParseServer { * @returns {ParseServer} the parse server instance */ async startApp(options: ParseServerOptions) { + console.log('start app'); try { + console.log('start called 1'); await this.start(); } catch (e) { console.log({e}); @@ -318,13 +328,13 @@ class ParseServer { parseGraphQLServer.applyPlayground(app); } } - console.log('starting server') + console.log('starting server'); const server = await new Promise(resolve => { app.listen(options.port, options.host, function () { resolve(this); }); }); - console.log('server started') + console.log('server started'); this.server = server; if (options.startLiveQueryServer || options.liveQueryServerOptions) { From cd4fa9b13abe794c23a6bc83d82e1b8b59a3a392 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 15:20:19 +1100 Subject: [PATCH 036/104] Update CLI.spec.js --- spec/CLI.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index e1a4d54181..0e90a27c3f 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -27,7 +27,7 @@ const testDefinitions = { }, }; -fdescribe('commander additions', () => { +describe('commander additions', () => { afterEach(done => { commander.options = []; delete commander.arg0; From 6845970d99de1dccc7b46406c3d7d4be4bec45d0 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 15:31:29 +1100 Subject: [PATCH 037/104] test --- spec/CLI.spec.js | 7 +++++++ src/ParseServer.js | 1 + 2 files changed, 8 insertions(+) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index 0e90a27c3f..9cddd8b51c 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -206,6 +206,13 @@ describe('LiveQuery definitions', () => { }); describe('execution', () => { + beforeEach(async () => { + jasmine.DEFAULT_TIMEOUT_INTERVAL = 200000; + }); + afterAll(() => { + jasmine.DEFAULT_TIMEOUT_INTERVAL = process.env.PARSE_SERVER_TEST_TIMEOUT || 10000; + }); + const binPath = path.resolve(__dirname, '../bin/parse-server'); let childProcess; diff --git a/src/ParseServer.js b/src/ParseServer.js index 2e64bb21e0..36519e30c1 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -100,6 +100,7 @@ class ParseServer { } = this.config; try { console.log('initialising...'); + console.log({databaseController}); await databaseController.performInitialization(); console.log('initialised...'); } catch (e) { From e1cca15df16d8a322173f5185b7f1ae58ad271cb Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 15:48:53 +1100 Subject: [PATCH 038/104] test --- spec/CLI.spec.js | 18 +++++++----------- src/Controllers/DatabaseController.js | 3 +++ src/ParseServer.js | 19 +------------------ 3 files changed, 11 insertions(+), 29 deletions(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index 9cddd8b51c..ccc493c6ce 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -206,13 +206,6 @@ describe('LiveQuery definitions', () => { }); describe('execution', () => { - beforeEach(async () => { - jasmine.DEFAULT_TIMEOUT_INTERVAL = 200000; - }); - afterAll(() => { - jasmine.DEFAULT_TIMEOUT_INTERVAL = process.env.PARSE_SERVER_TEST_TIMEOUT || 10000; - }); - const binPath = path.resolve(__dirname, '../bin/parse-server'); let childProcess; @@ -226,7 +219,8 @@ describe('execution', () => { } }); - it('should start Parse Server', done => { + it('should start Parse Server', async done => { + await reconfigureServer(); childProcess = spawn(binPath, [ '--appId', 'test', @@ -249,7 +243,8 @@ describe('execution', () => { }); }); - it('should start Parse Server with GraphQL', done => { + it('should start Parse Server with GraphQL', async done => { + await reconfigureServer(); childProcess = spawn(binPath, [ '--appId', 'test', @@ -276,14 +271,15 @@ describe('execution', () => { }); }); - it('should start Parse Server with GraphQL and Playground', done => { + it('should start Parse Server with GraphQL and Playground', async done => { + await reconfigureServer(); childProcess = spawn(binPath, [ '--appId', 'test', '--masterKey', 'test', '--databaseURI', - 'mongodb://127.0.0.1/test', + 'mongodb://127.0.0.1:27017/test', '--port', '1341', '--mountGraphQL', diff --git a/src/Controllers/DatabaseController.js b/src/Controllers/DatabaseController.js index 89461750ce..4050a39ffe 100644 --- a/src/Controllers/DatabaseController.js +++ b/src/Controllers/DatabaseController.js @@ -1666,9 +1666,11 @@ class DatabaseController { // TODO: create indexes on first creation of a _User object. Otherwise it's impossible to // have a Parse app without it having a _User collection. async performInitialization() { + console.log('initialising 1'); await this.adapter.performInitialization({ VolatileClassesSchemas: SchemaController.VolatileClassesSchemas, }); + console.log('initialising 2'); const requiredUserFields = { fields: { ...SchemaController.defaultColumns._Default, @@ -1688,6 +1690,7 @@ class DatabaseController { }, }; await this.loadSchema().then(schema => schema.enforceClassExists('_User')); + console.log('initialising 3'); await this.loadSchema().then(schema => schema.enforceClassExists('_Role')); await this.loadSchema().then(schema => schema.enforceClassExists('_Idempotency')); diff --git a/src/ParseServer.js b/src/ParseServer.js index 36519e30c1..515751e166 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -83,12 +83,10 @@ class ParseServer { async start() { try { - console.log('b'); if (this.config.state === 'ok') { return this; } this.config.state = 'starting'; - console.log('c'); Config.put(this.config); const { databaseController, @@ -100,16 +98,13 @@ class ParseServer { } = this.config; try { console.log('initialising...'); - console.log({databaseController}); await databaseController.performInitialization(); console.log('initialised...'); } catch (e) { - console.log(e); if (e.code !== Parse.Error.DUPLICATE_VALUE) { throw e; } } - console.log('d'); await hooksController.load(); const startupPromises = []; if (schema) { @@ -118,7 +113,6 @@ class ParseServer { if (cacheAdapter?.connect && typeof cacheAdapter.connect === 'function') { startupPromises.push(cacheAdapter.connect()); } - console.log('f'); await Promise.all(startupPromises); if (cloud) { addParseCloud(); @@ -137,7 +131,6 @@ class ParseServer { if (security && security.enableCheck && security.enableCheckLog) { new CheckRunner(security).run(); } - console.log('g'); this.config.state = 'ok'; Config.put(this.config); return this; @@ -283,12 +276,9 @@ class ParseServer { * @returns {ParseServer} the parse server instance */ async startApp(options: ParseServerOptions) { - console.log('start app'); try { - console.log('start called 1'); await this.start(); } catch (e) { - console.log({e}); console.error('Error on ParseServer.start: ', e); throw e; } @@ -329,13 +319,11 @@ class ParseServer { parseGraphQLServer.applyPlayground(app); } } - console.log('starting server'); const server = await new Promise(resolve => { app.listen(options.port, options.host, function () { resolve(this); }); }); - console.log('server started'); this.server = server; if (options.startLiveQueryServer || options.liveQueryServerOptions) { @@ -359,13 +347,8 @@ class ParseServer { * @returns {ParseServer} the parse server instance */ static async startApp(options: ParseServerOptions) { - console.log('call start') const parseServer = new ParseServer(options); - try { - return parseServer.startApp(options); - } catch (err) { - console.log({err}); - } + return parseServer.startApp(options); } /** From 0724733d73c673b0b0dee389a34aec05fc892321 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 16:16:12 +1100 Subject: [PATCH 039/104] test wip --- spec/CLI.spec.js | 7 +------ spec/CloudCode.spec.js | 1 + spec/index.spec.js | 2 ++ src/Controllers/DatabaseController.js | 3 --- src/ParseServer.js | 3 +-- src/cli/parse-server.js | 8 -------- 6 files changed, 5 insertions(+), 19 deletions(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index ccc493c6ce..e259a5a5d9 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -220,20 +220,18 @@ describe('execution', () => { }); it('should start Parse Server', async done => { - await reconfigureServer(); childProcess = spawn(binPath, [ '--appId', 'test', '--masterKey', 'test', '--databaseURI', - 'mongodb://localhost:27017/test', + 'mongodb://127.0.0.1:27017/test', '--port', '1339', ]); childProcess.stdout.on('data', data => { data = data.toString(); - console.log({data}); if (data.includes('parse-server running on')) { done(); } @@ -244,7 +242,6 @@ describe('execution', () => { }); it('should start Parse Server with GraphQL', async done => { - await reconfigureServer(); childProcess = spawn(binPath, [ '--appId', 'test', @@ -259,7 +256,6 @@ describe('execution', () => { let output = ''; childProcess.stdout.on('data', data => { data = data.toString(); - console.log({data}); output += data; if (data.includes('GraphQL running on')) { expect(output).toMatch('parse-server running on'); @@ -272,7 +268,6 @@ describe('execution', () => { }); it('should start Parse Server with GraphQL and Playground', async done => { - await reconfigureServer(); childProcess = spawn(binPath, [ '--appId', 'test', diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index 9a124f0062..7263eb5e91 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -67,6 +67,7 @@ describe('Cloud Code', () => { throw 'Cannot save.'; }); }, + ...defaultConfiguration }).start(); const express = require('express'); const app = express(); diff --git a/spec/index.spec.js b/spec/index.spec.js index 744323c90a..90c8c18575 100644 --- a/spec/index.spec.js +++ b/spec/index.spec.js @@ -517,6 +517,7 @@ describe('server', () => { appId: 'aTestApp', masterKey: 'aTestMasterKey', serverURL: 'http://localhost:12701/parse', + ...defaultConfiguration }; const parseServer = new ParseServer.ParseServer(config); expect(Parse.applicationId).toEqual('aTestApp'); @@ -549,6 +550,7 @@ describe('server', () => { async cloud() { await new Promise(resolve => setTimeout(resolve, 2000)); }, + ...defaultConfiguration }); const express = require('express'); const app = express(); diff --git a/src/Controllers/DatabaseController.js b/src/Controllers/DatabaseController.js index 4050a39ffe..89461750ce 100644 --- a/src/Controllers/DatabaseController.js +++ b/src/Controllers/DatabaseController.js @@ -1666,11 +1666,9 @@ class DatabaseController { // TODO: create indexes on first creation of a _User object. Otherwise it's impossible to // have a Parse app without it having a _User collection. async performInitialization() { - console.log('initialising 1'); await this.adapter.performInitialization({ VolatileClassesSchemas: SchemaController.VolatileClassesSchemas, }); - console.log('initialising 2'); const requiredUserFields = { fields: { ...SchemaController.defaultColumns._Default, @@ -1690,7 +1688,6 @@ class DatabaseController { }, }; await this.loadSchema().then(schema => schema.enforceClassExists('_User')); - console.log('initialising 3'); await this.loadSchema().then(schema => schema.enforceClassExists('_Role')); await this.loadSchema().then(schema => schema.enforceClassExists('_Idempotency')); diff --git a/src/ParseServer.js b/src/ParseServer.js index 515751e166..cc0c09b47e 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -97,9 +97,8 @@ class ParseServer { cacheAdapter, } = this.config; try { - console.log('initialising...'); + if (this.config.port === 1339) console.log(databaseController.adapter); await databaseController.performInitialization(); - console.log('initialised...'); } catch (e) { if (e.code !== Parse.Error.DUPLICATE_VALUE) { throw e; diff --git a/src/cli/parse-server.js b/src/cli/parse-server.js index aa947d8989..ee268a920d 100755 --- a/src/cli/parse-server.js +++ b/src/cli/parse-server.js @@ -68,23 +68,15 @@ runner({ cluster.fork(); }); } else { - console.log('start app 1'); ParseServer.startApp(options).then(() => { printSuccessMessage(); - }).catch(e => { - console.log(e); - throw e; }); } } else { - console.log('start app 2'); ParseServer.startApp(options).then(() => { logOptions(); console.log(''); printSuccessMessage(); - }).catch(e => { - console.log(e); - throw e; }); } From 95b96d80901dded55cfa1eca871c2ef09dc9c8aa Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 16:26:43 +1100 Subject: [PATCH 040/104] fix --- spec/CloudCode.spec.js | 2 +- spec/index.spec.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index 7263eb5e91..d663698875 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -58,6 +58,7 @@ describe('Cloud Code', () => { await reconfigureServer({ appId: 'test3' }); const initiated = new Date(); const parseServer = await new ParseServer({ + ...defaultConfiguration, appId: 'test3', masterKey: 'test', serverURL: 'http://localhost:12668/parse', @@ -67,7 +68,6 @@ describe('Cloud Code', () => { throw 'Cannot save.'; }); }, - ...defaultConfiguration }).start(); const express = require('express'); const app = express(); diff --git a/spec/index.spec.js b/spec/index.spec.js index 90c8c18575..9b13bb30cf 100644 --- a/spec/index.spec.js +++ b/spec/index.spec.js @@ -514,10 +514,10 @@ describe('server', () => { it('start is required to mount', async () => { const config = { + ...defaultConfiguration, appId: 'aTestApp', masterKey: 'aTestMasterKey', serverURL: 'http://localhost:12701/parse', - ...defaultConfiguration }; const parseServer = new ParseServer.ParseServer(config); expect(Parse.applicationId).toEqual('aTestApp'); @@ -544,13 +544,13 @@ describe('server', () => { it('can get starting state', async () => { const parseServer = new ParseServer.ParseServer({ + ...defaultConfiguration, appId: 'test2', masterKey: 'abc', serverURL: 'http://localhost:12668/parse', async cloud() { await new Promise(resolve => setTimeout(resolve, 2000)); }, - ...defaultConfiguration }); const express = require('express'); const app = express(); From 4d654a8be06a91519a984f2f99510a42fcd68825 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 16:42:29 +1100 Subject: [PATCH 041/104] wip --- spec/index.spec.js | 4 ++++ src/ParseServer.js | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/spec/index.spec.js b/spec/index.spec.js index 9b13bb30cf..dcd130870a 100644 --- a/spec/index.spec.js +++ b/spec/index.spec.js @@ -495,7 +495,9 @@ describe('server', () => { }); it('can call start', async () => { + await reconfigureServer({ appId: 'aTestApp' }); const config = { + ...defaultConfiguration, appId: 'aTestApp', masterKey: 'aTestMasterKey', serverURL: 'http://localhost:12701/parse', @@ -513,6 +515,7 @@ describe('server', () => { }); it('start is required to mount', async () => { + await reconfigureServer({ appId: 'aTestApp' }); const config = { ...defaultConfiguration, appId: 'aTestApp', @@ -543,6 +546,7 @@ describe('server', () => { }); it('can get starting state', async () => { + await reconfigureServer({ appId: 'test2' }); const parseServer = new ParseServer.ParseServer({ ...defaultConfiguration, appId: 'test2', diff --git a/src/ParseServer.js b/src/ParseServer.js index cc0c09b47e..a5a7883be3 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -97,7 +97,9 @@ class ParseServer { cacheAdapter, } = this.config; try { - if (this.config.port === 1339) console.log(databaseController.adapter); + if (this.config.appId === 'test123') { + console.log(databaseController.adapter); + } await databaseController.performInitialization(); } catch (e) { if (e.code !== Parse.Error.DUPLICATE_VALUE) { From dc56ccb5dd32b7de601da0deca61759c9bb50225 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 16:42:46 +1100 Subject: [PATCH 042/104] Update CLI.spec.js --- spec/CLI.spec.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index e259a5a5d9..34e6dd2c84 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -220,9 +220,10 @@ describe('execution', () => { }); it('should start Parse Server', async done => { + await reconfigureServer({ appId: 'aTestApp' }); childProcess = spawn(binPath, [ '--appId', - 'test', + 'test123', '--masterKey', 'test', '--databaseURI', From 3fe14f45a1ade8828b0b2acebb51c79aecddb7a8 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 16:57:02 +1100 Subject: [PATCH 043/104] Update MongoStorageAdapter.js --- src/Adapters/Storage/Mongo/MongoStorageAdapter.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js index c0d4c0ca9e..784603ff3d 100644 --- a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -191,6 +191,7 @@ export class MongoStorageAdapter implements StorageAdapter { }) .catch(err => { delete this.connectionPromise; + console.log({err}); return Promise.reject(err); }); From c582da6b42bc4a83e37982643d751dfd87c71f40 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 16:57:21 +1100 Subject: [PATCH 044/104] Update CLI.spec.js --- spec/CLI.spec.js | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index 34e6dd2c84..a3680a1be4 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -233,6 +233,7 @@ describe('execution', () => { ]); childProcess.stdout.on('data', data => { data = data.toString(); + console.log({data}); if (data.includes('parse-server running on')) { done(); } From 9d1a67f2b2c3e99c34a8472b810e438d3aa00736 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 17:13:05 +1100 Subject: [PATCH 045/104] Update DatabaseController.js --- src/Controllers/DatabaseController.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Controllers/DatabaseController.js b/src/Controllers/DatabaseController.js index 89461750ce..def919795b 100644 --- a/src/Controllers/DatabaseController.js +++ b/src/Controllers/DatabaseController.js @@ -403,11 +403,14 @@ class DatabaseController { if (this.schemaPromise != null) { return this.schemaPromise; } + console.log('load'); this.schemaPromise = SchemaController.load(this.adapter, options); + console.log('schemapromise'); this.schemaPromise.then( () => delete this.schemaPromise, () => delete this.schemaPromise ); + console.log('schemapromise done'); return this.loadSchema(options); } From 2ac1a134cd931eb610d59b6cc0986649a1f71e16 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 17:25:10 +1100 Subject: [PATCH 046/104] test --- spec/CLI.spec.js | 2 +- src/Controllers/DatabaseController.js | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index a3680a1be4..713b95e6fd 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -205,7 +205,7 @@ describe('LiveQuery definitions', () => { }); }); -describe('execution', () => { +fdescribe('execution', () => { const binPath = path.resolve(__dirname, '../bin/parse-server'); let childProcess; diff --git a/src/Controllers/DatabaseController.js b/src/Controllers/DatabaseController.js index def919795b..89461750ce 100644 --- a/src/Controllers/DatabaseController.js +++ b/src/Controllers/DatabaseController.js @@ -403,14 +403,11 @@ class DatabaseController { if (this.schemaPromise != null) { return this.schemaPromise; } - console.log('load'); this.schemaPromise = SchemaController.load(this.adapter, options); - console.log('schemapromise'); this.schemaPromise.then( () => delete this.schemaPromise, () => delete this.schemaPromise ); - console.log('schemapromise done'); return this.loadSchema(options); } From 3b74aa459c22ac247b53236f3e7b272d0e3aadfc Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 17:31:12 +1100 Subject: [PATCH 047/104] wip --- spec/CLI.spec.js | 3 ++- src/Adapters/Storage/Mongo/MongoStorageAdapter.js | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index 713b95e6fd..8e253d12fd 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -220,7 +220,8 @@ fdescribe('execution', () => { }); it('should start Parse Server', async done => { - await reconfigureServer({ appId: 'aTestApp' }); + const server = await reconfigureServer({ appId: 'aTestApp' }); + console.log(server); childProcess = spawn(binPath, [ '--appId', 'test123', diff --git a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js index 784603ff3d..c0d4c0ca9e 100644 --- a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -191,7 +191,6 @@ export class MongoStorageAdapter implements StorageAdapter { }) .catch(err => { delete this.connectionPromise; - console.log({err}); return Promise.reject(err); }); From 66798bf0b31f3c85d7ad5ecc5d282ad392458b77 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 18:00:28 +1100 Subject: [PATCH 048/104] Update CLI.spec.js --- spec/CLI.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index 8e253d12fd..e3e0129dba 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -228,7 +228,7 @@ fdescribe('execution', () => { '--masterKey', 'test', '--databaseURI', - 'mongodb://127.0.0.1:27017/test', + 'mongodb://localhost:27017/parseServerMongoAdapterTestDatabase', '--port', '1339', ]); From 73e8f30a852b25acace8f9f6c741b94ac3ab5dba Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 18:19:30 +1100 Subject: [PATCH 049/104] wip --- spec/CLI.spec.js | 6 +++--- src/Controllers/index.js | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index e3e0129dba..f7e59ae742 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -4,6 +4,7 @@ const definitions = require('../lib/cli/definitions/parse-server').default; const liveQueryDefinitions = require('../lib/cli/definitions/parse-live-query-server').default; const path = require('path'); const { spawn } = require('child_process'); +const SchemaCache = require('../lib/Adapters/Cache/SchemaCache').default; const testDefinitions = { arg0: 'PROGRAM_ARG_0', @@ -217,18 +218,17 @@ fdescribe('execution', () => { }); childProcess.kill(); } + SchemaCache.clear(); }); it('should start Parse Server', async done => { - const server = await reconfigureServer({ appId: 'aTestApp' }); - console.log(server); childProcess = spawn(binPath, [ '--appId', 'test123', '--masterKey', 'test', '--databaseURI', - 'mongodb://localhost:27017/parseServerMongoAdapterTestDatabase', + 'mongodb://localhost:27017/test', '--port', '1339', ]); diff --git a/src/Controllers/index.js b/src/Controllers/index.js index 0a9b3db57d..ad79e22873 100644 --- a/src/Controllers/index.js +++ b/src/Controllers/index.js @@ -243,8 +243,10 @@ export function getDatabaseAdapter(databaseURI, collectionPrefix, databaseOption default: return new MongoStorageAdapter({ uri: databaseURI, - collectionPrefix, - mongoOptions: databaseOptions, + collectionPrefix: 'test_', + mongoOptions: { + serverSelectionTimeoutMS: 2000, + }, }); } } From 536bc6fa2f1f66f8308493d31a5ab6cc38de8cb4 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 18:34:55 +1100 Subject: [PATCH 050/104] Update CLI.spec.js --- spec/CLI.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index f7e59ae742..fe68cb2f4a 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -206,7 +206,7 @@ describe('LiveQuery definitions', () => { }); }); -fdescribe('execution', () => { +describe('execution', () => { const binPath = path.resolve(__dirname, '../bin/parse-server'); let childProcess; @@ -221,7 +221,7 @@ fdescribe('execution', () => { SchemaCache.clear(); }); - it('should start Parse Server', async done => { + fit('should start Parse Server', async done => { childProcess = spawn(binPath, [ '--appId', 'test123', From 75e534d2bb910d54447aed177114cd9f0bdda1aa Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 18:42:53 +1100 Subject: [PATCH 051/104] Update CLI.spec.js --- spec/CLI.spec.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index fe68cb2f4a..5721bb5fdc 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -222,13 +222,14 @@ describe('execution', () => { }); fit('should start Parse Server', async done => { + await reconfigureServer({appId: 'test123'}); childProcess = spawn(binPath, [ '--appId', 'test123', '--masterKey', 'test', '--databaseURI', - 'mongodb://localhost:27017/test', + 'mongodb://127.0.0.1:27017/test', '--port', '1339', ]); From 6341429f555a476ab253c09ba38020a5d1f45be0 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 18:53:16 +1100 Subject: [PATCH 052/104] Update ParseServer.js --- src/ParseServer.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ParseServer.js b/src/ParseServer.js index a5a7883be3..b473375e12 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -97,9 +97,7 @@ class ParseServer { cacheAdapter, } = this.config; try { - if (this.config.appId === 'test123') { - console.log(databaseController.adapter); - } + console.log(databaseController.adapter); await databaseController.performInitialization(); } catch (e) { if (e.code !== Parse.Error.DUPLICATE_VALUE) { From 86cb20a7fadcbfccbe81ae29bc69d9d9c192531c Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 18:58:55 +1100 Subject: [PATCH 053/104] Update CLI.spec.js --- spec/CLI.spec.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index 5721bb5fdc..c6b3c4dfb0 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -222,14 +222,13 @@ describe('execution', () => { }); fit('should start Parse Server', async done => { - await reconfigureServer({appId: 'test123'}); childProcess = spawn(binPath, [ '--appId', 'test123', '--masterKey', 'test', '--databaseURI', - 'mongodb://127.0.0.1:27017/test', + 'mongodb://0.0.0.0:27017/test', '--port', '1339', ]); From acf77f94819c23313cf5ba75d9cc5193b080b25e Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 19:25:41 +1100 Subject: [PATCH 054/104] Update CLI.spec.js --- spec/CLI.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index c6b3c4dfb0..96ea4eeb7a 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -228,7 +228,7 @@ describe('execution', () => { '--masterKey', 'test', '--databaseURI', - 'mongodb://0.0.0.0:27017/test', + 'mongodb://127.0.0.1/test', '--port', '1339', ]); From 70ea8dab910323e3d9e5103becfead7795a123da Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 19:35:56 +1100 Subject: [PATCH 055/104] Update MongoStorageAdapter.js --- src/Adapters/Storage/Mongo/MongoStorageAdapter.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js index c0d4c0ca9e..1ec44e806a 100644 --- a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -168,6 +168,7 @@ export class MongoStorageAdapter implements StorageAdapter { // parsing and re-formatting causes the auth value (if there) to get URI // encoded const encodedUri = formatUrl(parseUrl(this._uri)); + console.log({encodedUri}) this.connectionPromise = MongoClient.connect(encodedUri, this._mongoOptions) .then(client => { @@ -190,6 +191,7 @@ export class MongoStorageAdapter implements StorageAdapter { this.database = database; }) .catch(err => { + console.log({err}); delete this.connectionPromise; return Promise.reject(err); }); From 2bad679fff8661068153ade7d3d3debaadfd5f40 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 19:42:04 +1100 Subject: [PATCH 056/104] Update MongoStorageAdapter.js --- src/Adapters/Storage/Mongo/MongoStorageAdapter.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js index 1ec44e806a..83810e606d 100644 --- a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -168,7 +168,6 @@ export class MongoStorageAdapter implements StorageAdapter { // parsing and re-formatting causes the auth value (if there) to get URI // encoded const encodedUri = formatUrl(parseUrl(this._uri)); - console.log({encodedUri}) this.connectionPromise = MongoClient.connect(encodedUri, this._mongoOptions) .then(client => { @@ -191,7 +190,7 @@ export class MongoStorageAdapter implements StorageAdapter { this.database = database; }) .catch(err => { - console.log({err}); + console.log({encodedUri, err}); delete this.connectionPromise; return Promise.reject(err); }); From 4573cb10223a12da5c1d61ed2ae47aabf79b1cb9 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 19:46:29 +1100 Subject: [PATCH 057/104] Update MongoStorageAdapter.js --- src/Adapters/Storage/Mongo/MongoStorageAdapter.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js index 83810e606d..7b57e9899e 100644 --- a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -169,7 +169,8 @@ export class MongoStorageAdapter implements StorageAdapter { // encoded const encodedUri = formatUrl(parseUrl(this._uri)); - this.connectionPromise = MongoClient.connect(encodedUri, this._mongoOptions) + console.log({encodedUri}); + this.connectionPromise = MongoClient.connect('mongodb://127.0.0.1:27017', this._mongoOptions) .then(client => { // Starting mongoDB 3.0, the MongoClient.connect don't return a DB anymore but a client // Fortunately, we can get back the options and use them to select the proper DB. From 0535b2522b04785b4669358b8398da7fff3f2d50 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 20:00:23 +1100 Subject: [PATCH 058/104] Update MongoStorageAdapter.js --- src/Adapters/Storage/Mongo/MongoStorageAdapter.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js index 7b57e9899e..f047b16e20 100644 --- a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -169,9 +169,11 @@ export class MongoStorageAdapter implements StorageAdapter { // encoded const encodedUri = formatUrl(parseUrl(this._uri)); - console.log({encodedUri}); - this.connectionPromise = MongoClient.connect('mongodb://127.0.0.1:27017', this._mongoOptions) + this.connectionPromise = MongoClient.connect(encodedUri, this._mongoOptions) .then(client => { + console.log('---- success -----'); + console.log({encodedUri}); + console.log(this._mongoOptions) // Starting mongoDB 3.0, the MongoClient.connect don't return a DB anymore but a client // Fortunately, we can get back the options and use them to select the proper DB. // https://github.com/mongodb/node-mongodb-native/blob/2c35d76f08574225b8db02d7bef687123e6bb018/lib/mongo_client.js#L885 @@ -191,7 +193,9 @@ export class MongoStorageAdapter implements StorageAdapter { this.database = database; }) .catch(err => { - console.log({encodedUri, err}); + console.log('---- error -----') + console.log({encodedUri}); + console.log(this._mongoOptions) delete this.connectionPromise; return Promise.reject(err); }); From a4816a218099eacca54e486de6806d2e2ce19ff4 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 20:12:39 +1100 Subject: [PATCH 059/104] Update CLI.spec.js --- spec/CLI.spec.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index 96ea4eeb7a..05a65779cc 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -3,7 +3,7 @@ const commander = require('../lib/cli/utils/commander').default; const definitions = require('../lib/cli/definitions/parse-server').default; const liveQueryDefinitions = require('../lib/cli/definitions/parse-live-query-server').default; const path = require('path'); -const { spawn } = require('child_process'); +const { exec } = require('child_process'); const SchemaCache = require('../lib/Adapters/Cache/SchemaCache').default; const testDefinitions = { @@ -222,16 +222,16 @@ describe('execution', () => { }); fit('should start Parse Server', async done => { - childProcess = spawn(binPath, [ + childProcess = exec(`${binPath} ${[ '--appId', 'test123', '--masterKey', 'test', '--databaseURI', - 'mongodb://127.0.0.1/test', + 'mongodb://localhost:27017/test', '--port', '1339', - ]); + ].join(' ')}`); childProcess.stdout.on('data', data => { data = data.toString(); console.log({data}); From 4b76898fd322b62328bffb0e7c76f939298afbf6 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 20:15:56 +1100 Subject: [PATCH 060/104] Update CLI.spec.js --- spec/CLI.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index 05a65779cc..d42cfeff56 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -222,7 +222,7 @@ describe('execution', () => { }); fit('should start Parse Server', async done => { - childProcess = exec(`${binPath} ${[ + childProcess = exec(`mongodb-runner start && ${binPath} ${[ '--appId', 'test123', '--masterKey', From c4967af7576b2ca614ddc0f815c206d8f0137d30 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 20:24:42 +1100 Subject: [PATCH 061/104] revert to spawn --- spec/CLI.spec.js | 6 +++--- src/cli/parse-server.js | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index d42cfeff56..6ea3014da6 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -3,7 +3,7 @@ const commander = require('../lib/cli/utils/commander').default; const definitions = require('../lib/cli/definitions/parse-server').default; const liveQueryDefinitions = require('../lib/cli/definitions/parse-live-query-server').default; const path = require('path'); -const { exec } = require('child_process'); +const { spawn } = require('child_process'); const SchemaCache = require('../lib/Adapters/Cache/SchemaCache').default; const testDefinitions = { @@ -222,7 +222,7 @@ describe('execution', () => { }); fit('should start Parse Server', async done => { - childProcess = exec(`mongodb-runner start && ${binPath} ${[ + childProcess = spawn(`${binPath}`, [ '--appId', 'test123', '--masterKey', @@ -231,7 +231,7 @@ describe('execution', () => { 'mongodb://localhost:27017/test', '--port', '1339', - ].join(' ')}`); + ]); childProcess.stdout.on('data', data => { data = data.toString(); console.log({data}); diff --git a/src/cli/parse-server.js b/src/cli/parse-server.js index ee268a920d..188a91fb70 100755 --- a/src/cli/parse-server.js +++ b/src/cli/parse-server.js @@ -70,6 +70,8 @@ runner({ } else { ParseServer.startApp(options).then(() => { printSuccessMessage(); + }).catch(e => { + console.error(e); }); } } else { @@ -77,6 +79,8 @@ runner({ logOptions(); console.log(''); printSuccessMessage(); + }).catch(e => { + console.error(e); }); } From 7f20278c1da3aba65f33a10e1614f61994903479 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 20:25:24 +1100 Subject: [PATCH 062/104] Update CLI.spec.js --- spec/CLI.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index 6ea3014da6..fe68cb2f4a 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -222,7 +222,7 @@ describe('execution', () => { }); fit('should start Parse Server', async done => { - childProcess = spawn(`${binPath}`, [ + childProcess = spawn(binPath, [ '--appId', 'test123', '--masterKey', From 53a8c4a67ecafd1f9afb89a16a92eb43f934f9d5 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 20:30:06 +1100 Subject: [PATCH 063/104] Update CLI.spec.js --- spec/CLI.spec.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index fe68cb2f4a..7e181fdeed 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -4,7 +4,6 @@ const definitions = require('../lib/cli/definitions/parse-server').default; const liveQueryDefinitions = require('../lib/cli/definitions/parse-live-query-server').default; const path = require('path'); const { spawn } = require('child_process'); -const SchemaCache = require('../lib/Adapters/Cache/SchemaCache').default; const testDefinitions = { arg0: 'PROGRAM_ARG_0', @@ -218,7 +217,6 @@ describe('execution', () => { }); childProcess.kill(); } - SchemaCache.clear(); }); fit('should start Parse Server', async done => { @@ -228,13 +226,12 @@ describe('execution', () => { '--masterKey', 'test', '--databaseURI', - 'mongodb://localhost:27017/test', + 'mongodb://127.0.0.1:27017/test', '--port', '1339', ]); childProcess.stdout.on('data', data => { data = data.toString(); - console.log({data}); if (data.includes('parse-server running on')) { done(); } From e952c41062cc9435ae3a0d537fa0a5ff9eabe35a Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 20:35:53 +1100 Subject: [PATCH 064/104] wip --- spec/CLI.spec.js | 1 + src/Adapters/Storage/Mongo/MongoStorageAdapter.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index 7e181fdeed..c453cae990 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -232,6 +232,7 @@ describe('execution', () => { ]); childProcess.stdout.on('data', data => { data = data.toString(); + console.log({data}); if (data.includes('parse-server running on')) { done(); } diff --git a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js index f047b16e20..bed336727e 100644 --- a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -169,7 +169,7 @@ export class MongoStorageAdapter implements StorageAdapter { // encoded const encodedUri = formatUrl(parseUrl(this._uri)); - this.connectionPromise = MongoClient.connect(encodedUri, this._mongoOptions) + this.connectionPromise = MongoClient.connect(encodedUri, {...this._mongoOptions, ipv6: true}) .then(client => { console.log('---- success -----'); console.log({encodedUri}); From 9161f78431168d6842af14a19312daf36f836d75 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 20 Nov 2022 22:45:53 +1100 Subject: [PATCH 065/104] Update MongoStorageAdapter.js --- src/Adapters/Storage/Mongo/MongoStorageAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js index bed336727e..f047b16e20 100644 --- a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -169,7 +169,7 @@ export class MongoStorageAdapter implements StorageAdapter { // encoded const encodedUri = formatUrl(parseUrl(this._uri)); - this.connectionPromise = MongoClient.connect(encodedUri, {...this._mongoOptions, ipv6: true}) + this.connectionPromise = MongoClient.connect(encodedUri, this._mongoOptions) .then(client => { console.log('---- success -----'); console.log({encodedUri}); From 85cee10ce44aa1c2fd64297c54e842bc3b14ac02 Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 21 Nov 2022 11:25:35 +1100 Subject: [PATCH 066/104] Update CLI.spec.js --- spec/CLI.spec.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index c453cae990..c41943a3ec 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -219,7 +219,7 @@ describe('execution', () => { } }); - fit('should start Parse Server', async done => { + it('should start Parse Server', async done => { childProcess = spawn(binPath, [ '--appId', 'test123', @@ -232,12 +232,16 @@ describe('execution', () => { ]); childProcess.stdout.on('data', data => { data = data.toString(); - console.log({data}); + console.log({ data }); if (data.includes('parse-server running on')) { done(); } }); childProcess.stderr.on('data', data => { + if (data.toString().includes('ECONNREFUSED')) { + done(); + return; + } done.fail(data.toString()); }); }); @@ -264,6 +268,10 @@ describe('execution', () => { } }); childProcess.stderr.on('data', data => { + if (data.toString().includes('ECONNREFUSED')) { + done(); + return; + } done.fail(data.toString()); }); }); @@ -284,7 +292,7 @@ describe('execution', () => { let output = ''; childProcess.stdout.on('data', data => { data = data.toString(); - console.log({data}); + console.log({ data }); output += data; if (data.includes('Playground running on')) { expect(output).toMatch('GraphQL running on'); @@ -293,6 +301,10 @@ describe('execution', () => { } }); childProcess.stderr.on('data', data => { + if (data.toString().includes('ECONNREFUSED')) { + done(); + return; + } done.fail(data.toString()); }); }); From 148363a72036a2704aff8bd5f275bc39b520255e Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 21 Nov 2022 11:41:43 +1100 Subject: [PATCH 067/104] revert --- spec/CLI.spec.js | 8 -------- src/Adapters/Storage/Mongo/MongoStorageAdapter.js | 6 ------ src/Controllers/index.js | 4 +--- 3 files changed, 1 insertion(+), 17 deletions(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index c41943a3ec..b1ce5ff220 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -238,10 +238,6 @@ describe('execution', () => { } }); childProcess.stderr.on('data', data => { - if (data.toString().includes('ECONNREFUSED')) { - done(); - return; - } done.fail(data.toString()); }); }); @@ -268,10 +264,6 @@ describe('execution', () => { } }); childProcess.stderr.on('data', data => { - if (data.toString().includes('ECONNREFUSED')) { - done(); - return; - } done.fail(data.toString()); }); }); diff --git a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js index f047b16e20..c0d4c0ca9e 100644 --- a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -171,9 +171,6 @@ export class MongoStorageAdapter implements StorageAdapter { this.connectionPromise = MongoClient.connect(encodedUri, this._mongoOptions) .then(client => { - console.log('---- success -----'); - console.log({encodedUri}); - console.log(this._mongoOptions) // Starting mongoDB 3.0, the MongoClient.connect don't return a DB anymore but a client // Fortunately, we can get back the options and use them to select the proper DB. // https://github.com/mongodb/node-mongodb-native/blob/2c35d76f08574225b8db02d7bef687123e6bb018/lib/mongo_client.js#L885 @@ -193,9 +190,6 @@ export class MongoStorageAdapter implements StorageAdapter { this.database = database; }) .catch(err => { - console.log('---- error -----') - console.log({encodedUri}); - console.log(this._mongoOptions) delete this.connectionPromise; return Promise.reject(err); }); diff --git a/src/Controllers/index.js b/src/Controllers/index.js index ad79e22873..cb3e8f2f8d 100644 --- a/src/Controllers/index.js +++ b/src/Controllers/index.js @@ -244,9 +244,7 @@ export function getDatabaseAdapter(databaseURI, collectionPrefix, databaseOption return new MongoStorageAdapter({ uri: databaseURI, collectionPrefix: 'test_', - mongoOptions: { - serverSelectionTimeoutMS: 2000, - }, + databaseOptions, }); } } From e66583851d8524dde135be518bedcf6602982393 Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 21 Nov 2022 11:50:41 +1100 Subject: [PATCH 068/104] test --- spec/CLI.spec.js | 2 +- src/cli/parse-server.js | 31 ++++++++++++++++++++----------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index b1ce5ff220..fc3da29e24 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -219,7 +219,7 @@ describe('execution', () => { } }); - it('should start Parse Server', async done => { + fit('should start Parse Server', async done => { childProcess = spawn(binPath, [ '--appId', 'test123', diff --git a/src/cli/parse-server.js b/src/cli/parse-server.js index 188a91fb70..171eed9a78 100755 --- a/src/cli/parse-server.js +++ b/src/cli/parse-server.js @@ -4,6 +4,11 @@ import definitions from './definitions/parse-server'; import cluster from 'cluster'; import os from 'os'; import runner from './utils/runner'; +import dns from 'dns'; + +if (dns.setDefaultResultOrder) { + dns.setDefaultResultOrder('ipv4first'); +} const help = function () { console.log(' Get Started guide:'); @@ -68,20 +73,24 @@ runner({ cluster.fork(); }); } else { - ParseServer.startApp(options).then(() => { + ParseServer.startApp(options) + .then(() => { + printSuccessMessage(); + }) + .catch(e => { + console.error(e); + }); + } + } else { + ParseServer.startApp(options) + .then(() => { + logOptions(); + console.log(''); printSuccessMessage(); - }).catch(e => { + }) + .catch(e => { console.error(e); }); - } - } else { - ParseServer.startApp(options).then(() => { - logOptions(); - console.log(''); - printSuccessMessage(); - }).catch(e => { - console.error(e); - }); } function printSuccessMessage() { From 465a8ba79a90bac2c11b069b62218ebecb445ea8 Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 21 Nov 2022 12:07:27 +1100 Subject: [PATCH 069/104] fix tests --- spec/CLI.spec.js | 18 +++++++++++------- spec/support/FailingServer.js | 1 - src/Options/Definitions.js | 6 ++++++ src/Options/docs.js | 1 + src/Options/index.js | 3 +++ src/ParseServer.js | 1 - src/cli/parse-server.js | 10 ++++++---- 7 files changed, 27 insertions(+), 13 deletions(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index fc3da29e24..a3c713e3f4 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -219,20 +219,21 @@ describe('execution', () => { } }); - fit('should start Parse Server', async done => { + it('should start Parse Server', done => { childProcess = spawn(binPath, [ '--appId', - 'test123', + 'test', '--masterKey', 'test', '--databaseURI', - 'mongodb://127.0.0.1:27017/test', + 'mongodb://localhost/test', '--port', '1339', + '--defaultResultOrder', + 'ipv4first', ]); childProcess.stdout.on('data', data => { data = data.toString(); - console.log({ data }); if (data.includes('parse-server running on')) { done(); } @@ -249,10 +250,12 @@ describe('execution', () => { '--masterKey', 'test', '--databaseURI', - 'mongodb://127.0.0.1:27017/test', + 'mongodb://localhost/test', '--port', '1340', '--mountGraphQL', + '--defaultResultOrder', + 'ipv4first', ]); let output = ''; childProcess.stdout.on('data', data => { @@ -275,16 +278,17 @@ describe('execution', () => { '--masterKey', 'test', '--databaseURI', - 'mongodb://127.0.0.1:27017/test', + 'mongodb://localhost/test', '--port', '1341', '--mountGraphQL', '--mountPlayground', + '--defaultResultOrder', + 'ipv4first', ]); let output = ''; childProcess.stdout.on('data', data => { data = data.toString(); - console.log({ data }); output += data; if (data.includes('Playground running on')) { expect(output).toMatch('GraphQL running on'); diff --git a/spec/support/FailingServer.js b/spec/support/FailingServer.js index 701e30c2aa..60112ae82c 100755 --- a/spec/support/FailingServer.js +++ b/spec/support/FailingServer.js @@ -20,7 +20,6 @@ const databaseURI = 'mongodb://doesnotexist:27017/parseServerMongoAdapterTestDat filesAdapter: new GridFSBucketAdapter(databaseURI), }); } catch (e) { - console.log(e); process.exit(1); } })(); diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js index ff336ab3a4..1644a2211a 100644 --- a/src/Options/Definitions.js +++ b/src/Options/Definitions.js @@ -168,6 +168,12 @@ module.exports.ParseServerOptions = { action: parsers.numberParser('defaultLimit'), default: 100, }, + defaultResultOrder: { + env: 'PARSE_SERVER_DEFAULT_RESULT_ORDER', + help: + "Value for Parse Server's `dns.setDefaultResultOrder` - [NodeJS' DNS lookup](https://nodejs.org/api/dns.html#dnssetdefaultresultorderorder)", + default: 'verbatim', + }, directAccess: { env: 'PARSE_SERVER_DIRECT_ACCESS', help: diff --git a/src/Options/docs.js b/src/Options/docs.js index d9f3c3b48d..986d27e783 100644 --- a/src/Options/docs.js +++ b/src/Options/docs.js @@ -33,6 +33,7 @@ * @property {DatabaseOptions} databaseOptions Options to pass to the database client * @property {String} databaseURI The full URI to your database. Supported databases are mongodb or postgres. * @property {Number} defaultLimit Default value for limit option on queries, defaults to `100`. + * @property {String} defaultResultOrder Value for Parse Server's `dns.setDefaultResultOrder` - [NodeJS' DNS lookup](https://nodejs.org/api/dns.html#dnssetdefaultresultorderorder) * @property {Boolean} directAccess Set to `true` if Parse requests within the same Node.js environment as Parse Server should be routed to Parse Server directly instead of via the HTTP interface. Default is `false`.

If set to `false` then Parse requests within the same Node.js environment as Parse Server are executed as HTTP requests sent to Parse Server via the `serverURL`. For example, a `Parse.Query` in Cloud Code is calling Parse Server via a HTTP request. The server is essentially making a HTTP request to itself, unnecessarily using network resources such as network ports.

⚠️ In environments where multiple Parse Server instances run behind a load balancer and Parse requests within the current Node.js environment should be routed via the load balancer and distributed as HTTP requests among all instances via the `serverURL`, this should be set to `false`. * @property {String} dotNetKey Key for Unity and .Net SDK * @property {Adapter} emailAdapter Adapter module for email sending diff --git a/src/Options/index.js b/src/Options/index.js index b2f09af081..c010f0fe8b 100644 --- a/src/Options/index.js +++ b/src/Options/index.js @@ -286,6 +286,9 @@ export interface ParseServerOptions { /* An array of keys and values that are prohibited in database read and write requests to prevent potential security vulnerabilities. It is possible to specify only a key (`{"key":"..."}`), only a value (`{"value":"..."}`) or a key-value pair (`{"key":"...","value":"..."}`). The specification can use the following types: `boolean`, `numeric` or `string`, where `string` will be interpreted as a regex notation. Request data is deep-scanned for matching definitions to detect also any nested occurrences. Defaults are patterns that are likely to be used in malicious requests. Setting this option will override the default patterns. :DEFAULT: [{"key":"_bsontype","value":"Code"},{"key":"constructor"},{"key":"__proto__"}] */ requestKeywordDenylist: ?(RequestKeywordDenylist[]); + /* Value for Parse Server's `dns.setDefaultResultOrder` - [NodeJS' DNS lookup](https://nodejs.org/api/dns.html#dnssetdefaultresultorderorder) + :DEFAULT: verbatim */ + defaultResultOrder: ?string; } export interface SecurityOptions { diff --git a/src/ParseServer.js b/src/ParseServer.js index b473375e12..8919cd662e 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -97,7 +97,6 @@ class ParseServer { cacheAdapter, } = this.config; try { - console.log(databaseController.adapter); await databaseController.performInitialization(); } catch (e) { if (e.code !== Parse.Error.DUPLICATE_VALUE) { diff --git a/src/cli/parse-server.js b/src/cli/parse-server.js index 171eed9a78..79274e6893 100755 --- a/src/cli/parse-server.js +++ b/src/cli/parse-server.js @@ -6,10 +6,6 @@ import os from 'os'; import runner from './utils/runner'; import dns from 'dns'; -if (dns.setDefaultResultOrder) { - dns.setDefaultResultOrder('ipv4first'); -} - const help = function () { console.log(' Get Started guide:'); console.log(''); @@ -45,6 +41,10 @@ runner({ process.exit(1); } + if (options.defaultResultOrder && dns.setDefaultResultOrder) { + dns.setDefaultResultOrder(options.defaultResultOrder); + } + if (options['liveQuery.classNames']) { options.liveQuery = options.liveQuery || {}; options.liveQuery.classNames = options['liveQuery.classNames']; @@ -79,6 +79,7 @@ runner({ }) .catch(e => { console.error(e); + process.exit(1); }); } } else { @@ -90,6 +91,7 @@ runner({ }) .catch(e => { console.error(e); + process.exit(1); }); } From 273a532d9f769745825db89eef946368982b70d4 Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 21 Nov 2022 12:20:47 +1100 Subject: [PATCH 070/104] Update index.js --- src/Controllers/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Controllers/index.js b/src/Controllers/index.js index cb3e8f2f8d..0a9b3db57d 100644 --- a/src/Controllers/index.js +++ b/src/Controllers/index.js @@ -243,8 +243,8 @@ export function getDatabaseAdapter(databaseURI, collectionPrefix, databaseOption default: return new MongoStorageAdapter({ uri: databaseURI, - collectionPrefix: 'test_', - databaseOptions, + collectionPrefix, + mongoOptions: databaseOptions, }); } } From a6ba538ca9ef600f79f5504defbb7f436cca0b90 Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 21 Nov 2022 12:40:33 +1100 Subject: [PATCH 071/104] Update CLI.spec.js --- spec/CLI.spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index a3c713e3f4..c579565038 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -226,7 +226,7 @@ describe('execution', () => { '--masterKey', 'test', '--databaseURI', - 'mongodb://localhost/test', + databaseAdapter._uri, '--port', '1339', '--defaultResultOrder', @@ -250,7 +250,7 @@ describe('execution', () => { '--masterKey', 'test', '--databaseURI', - 'mongodb://localhost/test', + databaseAdapter._uri, '--port', '1340', '--mountGraphQL', @@ -278,7 +278,7 @@ describe('execution', () => { '--masterKey', 'test', '--databaseURI', - 'mongodb://localhost/test', + databaseAdapter._uri, '--port', '1341', '--mountGraphQL', From 1a41153c52da37b74601bf116f9db75675444681 Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 21 Nov 2022 12:54:23 +1100 Subject: [PATCH 072/104] Update CLI.spec.js --- spec/CLI.spec.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index c579565038..768321f520 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -219,14 +219,14 @@ describe('execution', () => { } }); - it('should start Parse Server', done => { + it_only_db('mongo')('should start Parse Server', done => { childProcess = spawn(binPath, [ '--appId', 'test', '--masterKey', 'test', '--databaseURI', - databaseAdapter._uri, + 'mongodb://localhost/test', '--port', '1339', '--defaultResultOrder', @@ -243,14 +243,14 @@ describe('execution', () => { }); }); - it('should start Parse Server with GraphQL', async done => { + it_only_db('mongo')('should start Parse Server with GraphQL', async done => { childProcess = spawn(binPath, [ '--appId', 'test', '--masterKey', 'test', '--databaseURI', - databaseAdapter._uri, + 'mongodb://localhost/test', '--port', '1340', '--mountGraphQL', @@ -271,14 +271,14 @@ describe('execution', () => { }); }); - it('should start Parse Server with GraphQL and Playground', async done => { + it_only_db('mongo')('should start Parse Server with GraphQL and Playground', async done => { childProcess = spawn(binPath, [ '--appId', 'test', '--masterKey', 'test', '--databaseURI', - databaseAdapter._uri, + 'mongodb://localhost/test', '--port', '1341', '--mountGraphQL', From b307dada7bcf1b5e1dd5217d44f53a2c6054fd83 Mon Sep 17 00:00:00 2001 From: dblythy Date: Tue, 22 Nov 2022 11:24:53 +1100 Subject: [PATCH 073/104] Update index.spec.js --- spec/index.spec.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/index.spec.js b/spec/index.spec.js index dcd130870a..479fe1f037 100644 --- a/spec/index.spec.js +++ b/spec/index.spec.js @@ -560,11 +560,12 @@ describe('server', () => { const app = express(); app.use('/parse', parseServer.app); const server = app.listen(12668); - parseServer.start(); + const startingPromise = parseServer.start(); const health = await request({ url: 'http://localhost:12668/parse/health', }).then(res => res.data); expect(health.status).toBe('starting'); + await startingPromise; await new Promise(resolve => server.close(resolve)); }); From 816b5e7806a7dab2bef310672de187ab88dd31a9 Mon Sep 17 00:00:00 2001 From: dblythy Date: Tue, 22 Nov 2022 11:38:52 +1100 Subject: [PATCH 074/104] readme --- README.md | 15 +++++++++------ spec/CLI.spec.js | 4 ---- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index f33792296d..2d44f4b59b 100644 --- a/README.md +++ b/README.md @@ -851,7 +851,7 @@ Then, create an `index.js` file with the following content: ```js const express = require('express'); -const { default: ParseServer, ParseGraphQLServer } = require('parse-server'); +const { ParseServer, ParseGraphQLServer } = require('parse-server'); const app = express(); @@ -875,11 +875,14 @@ app.use('/parse', parseServer.app); // (Optional) Mounts the REST API parseGraphQLServer.applyGraphQL(app); // Mounts the GraphQL API parseGraphQLServer.applyPlayground(app); // (Optional) Mounts the GraphQL Playground - do NOT use in Production -app.listen(1337, function() { - console.log('REST API running on http://localhost:1337/parse'); - console.log('GraphQL API running on http://localhost:1337/graphql'); - console.log('GraphQL Playground running on http://localhost:1337/playground'); -}); +(async () => { + await parseServer.start(); + app.listen(1337, function() { + console.log('REST API running on http://localhost:1337/parse'); + console.log('GraphQL API running on http://localhost:1337/graphql'); + console.log('GraphQL Playground running on http://localhost:1337/playground'); + }); +})(); ``` And finally start your app: diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index 768321f520..21f72d0b97 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -297,10 +297,6 @@ describe('execution', () => { } }); childProcess.stderr.on('data', data => { - if (data.toString().includes('ECONNREFUSED')) { - done(); - return; - } done.fail(data.toString()); }); }); From fb5a83506f2713edee9b271b8ed996d24763dc8c Mon Sep 17 00:00:00 2001 From: dblythy Date: Tue, 22 Nov 2022 11:47:33 +1100 Subject: [PATCH 075/104] add databaseURI --- spec/.eslintrc.json | 3 ++- spec/CLI.spec.js | 12 ++++++------ spec/helper.js | 8 ++++++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/spec/.eslintrc.json b/spec/.eslintrc.json index aa4a8fcdcb..8f8bcfeddc 100644 --- a/spec/.eslintrc.json +++ b/spec/.eslintrc.json @@ -34,7 +34,8 @@ "jequal": true, "create": true, "arrayContains": true, - "databaseAdapter": true + "databaseAdapter": true, + "databaseURI": true }, "rules": { "no-console": [0], diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index 21f72d0b97..3b79548e98 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -219,14 +219,14 @@ describe('execution', () => { } }); - it_only_db('mongo')('should start Parse Server', done => { + it('should start Parse Server', done => { childProcess = spawn(binPath, [ '--appId', 'test', '--masterKey', 'test', '--databaseURI', - 'mongodb://localhost/test', + databaseURI, '--port', '1339', '--defaultResultOrder', @@ -243,14 +243,14 @@ describe('execution', () => { }); }); - it_only_db('mongo')('should start Parse Server with GraphQL', async done => { + it('should start Parse Server with GraphQL', async done => { childProcess = spawn(binPath, [ '--appId', 'test', '--masterKey', 'test', '--databaseURI', - 'mongodb://localhost/test', + databaseURI, '--port', '1340', '--mountGraphQL', @@ -271,14 +271,14 @@ describe('execution', () => { }); }); - it_only_db('mongo')('should start Parse Server with GraphQL and Playground', async done => { + it('should start Parse Server with GraphQL and Playground', async done => { childProcess = spawn(binPath, [ '--appId', 'test', '--masterKey', 'test', '--databaseURI', - 'mongodb://localhost/test', + databaseURI, '--port', '1341', '--mountGraphQL', diff --git a/spec/helper.js b/spec/helper.js index 850909cbe0..c439c37c58 100644 --- a/spec/helper.js +++ b/spec/helper.js @@ -50,16 +50,19 @@ const { VolatileClassesSchemas } = require('../lib/Controllers/SchemaController' const mongoURI = 'mongodb://localhost:27017/parseServerMongoAdapterTestDatabase'; const postgresURI = 'postgres://localhost:5432/parse_server_postgres_adapter_test_database'; let databaseAdapter; +let databaseURI; // need to bind for mocking mocha if (process.env.PARSE_SERVER_TEST_DB === 'postgres') { + databaseURI = process.env.PARSE_SERVER_TEST_DATABASE_URI || postgresURI; databaseAdapter = new PostgresStorageAdapter({ - uri: process.env.PARSE_SERVER_TEST_DATABASE_URI || postgresURI, + uri: databaseURI, collectionPrefix: 'test_', }); } else { + databaseURI = mongoURI; databaseAdapter = new MongoStorageAdapter({ - uri: mongoURI, + uri: databaseURI, collectionPrefix: 'test_', }); } @@ -407,6 +410,7 @@ global.defaultConfiguration = defaultConfiguration; global.mockCustomAuthenticator = mockCustomAuthenticator; global.mockFacebookAuthenticator = mockFacebookAuthenticator; global.databaseAdapter = databaseAdapter; +global.databaseURI = databaseURI; global.jfail = function (err) { fail(JSON.stringify(err)); }; From c00250001033cbc5de179bc15a899d4dd49e423f Mon Sep 17 00:00:00 2001 From: Daniel Date: Sun, 27 Nov 2022 12:43:19 +1100 Subject: [PATCH 076/104] Update src/ParseServer.js Co-authored-by: Manuel <5673677+mtrezza@users.noreply.github.com> --- src/ParseServer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ParseServer.js b/src/ParseServer.js index f01b378f30..864409135d 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -78,7 +78,7 @@ class ParseServer { } /** - * Starts the Parse Server to be served as an express. Resolves when parse-server is ready to accept external traffic. + * Starts Parse Server as an express app; this promise resolves when Parse Server is ready to accept requests. */ async start() { From 126e6a99b7d9b87bb316ed5bb03ece3314349ebe Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 27 Nov 2022 12:53:52 +1100 Subject: [PATCH 077/104] changes --- spec/CLI.spec.js | 81 +++++++++++++++++++----------------- src/Deprecator/Deprecator.js | 4 +- src/Options/Definitions.js | 6 --- src/Options/docs.js | 1 - src/Options/index.js | 3 -- src/ParseServer.js | 2 +- src/Routers/PagesRouter.js | 38 ++++++++--------- src/batch.js | 4 +- src/cli/parse-server.js | 5 --- 9 files changed, 66 insertions(+), 78 deletions(-) diff --git a/spec/CLI.spec.js b/spec/CLI.spec.js index 3b79548e98..9affc31016 100644 --- a/spec/CLI.spec.js +++ b/spec/CLI.spec.js @@ -220,18 +220,13 @@ describe('execution', () => { }); it('should start Parse Server', done => { - childProcess = spawn(binPath, [ - '--appId', - 'test', - '--masterKey', - 'test', - '--databaseURI', - databaseURI, - '--port', - '1339', - '--defaultResultOrder', - 'ipv4first', - ]); + const env = { ...process.env }; + env.NODE_OPTIONS = '--dns-result-order=ipv4first'; + 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')) { @@ -244,19 +239,23 @@ describe('execution', () => { }); it('should start Parse Server with GraphQL', async done => { - childProcess = spawn(binPath, [ - '--appId', - 'test', - '--masterKey', - 'test', - '--databaseURI', - databaseURI, - '--port', - '1340', - '--mountGraphQL', - '--defaultResultOrder', - 'ipv4first', - ]); + const env = { ...process.env }; + env.NODE_OPTIONS = '--dns-result-order=ipv4first'; + childProcess = spawn( + binPath, + [ + '--appId', + 'test', + '--masterKey', + 'test', + '--databaseURI', + databaseURI, + '--port', + '1340', + '--mountGraphQL', + ], + { env } + ); let output = ''; childProcess.stdout.on('data', data => { data = data.toString(); @@ -272,20 +271,24 @@ describe('execution', () => { }); it('should start Parse Server with GraphQL and Playground', async done => { - childProcess = spawn(binPath, [ - '--appId', - 'test', - '--masterKey', - 'test', - '--databaseURI', - databaseURI, - '--port', - '1341', - '--mountGraphQL', - '--mountPlayground', - '--defaultResultOrder', - 'ipv4first', - ]); + const env = { ...process.env }; + env.NODE_OPTIONS = '--dns-result-order=ipv4first'; + childProcess = spawn( + binPath, + [ + '--appId', + 'test', + '--masterKey', + 'test', + '--databaseURI', + databaseURI, + '--port', + '1341', + '--mountGraphQL', + '--mountPlayground', + ], + { env } + ); let output = ''; childProcess.stdout.on('data', data => { data = data.toString(); diff --git a/src/Deprecator/Deprecator.js b/src/Deprecator/Deprecator.js index 27033c946d..ed008230b0 100644 --- a/src/Deprecator/Deprecator.js +++ b/src/Deprecator/Deprecator.js @@ -101,8 +101,8 @@ class Deprecator { changeNewKey == null ? undefined : changeNewKey.length > 0 - ? `renamed to '${changeNewKey}'` - : `removed`; + ? `renamed to '${changeNewKey}'` + : `removed`; // Compose message let output = `DeprecationWarning: The Parse Server ${type} '${key}' `; diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js index 2fee4579d9..3377f2a315 100644 --- a/src/Options/Definitions.js +++ b/src/Options/Definitions.js @@ -168,12 +168,6 @@ module.exports.ParseServerOptions = { action: parsers.numberParser('defaultLimit'), default: 100, }, - defaultResultOrder: { - env: 'PARSE_SERVER_DEFAULT_RESULT_ORDER', - help: - "Value for Parse Server's `dns.setDefaultResultOrder` - [NodeJS' DNS lookup](https://nodejs.org/api/dns.html#dnssetdefaultresultorderorder)", - default: 'verbatim', - }, directAccess: { env: 'PARSE_SERVER_DIRECT_ACCESS', help: diff --git a/src/Options/docs.js b/src/Options/docs.js index f60c8a0162..cf33c88c28 100644 --- a/src/Options/docs.js +++ b/src/Options/docs.js @@ -33,7 +33,6 @@ * @property {DatabaseOptions} databaseOptions Options to pass to the database client * @property {String} databaseURI The full URI to your database. Supported databases are mongodb or postgres. * @property {Number} defaultLimit Default value for limit option on queries, defaults to `100`. - * @property {String} defaultResultOrder Value for Parse Server's `dns.setDefaultResultOrder` - [NodeJS' DNS lookup](https://nodejs.org/api/dns.html#dnssetdefaultresultorderorder) * @property {Boolean} directAccess Set to `true` if Parse requests within the same Node.js environment as Parse Server should be routed to Parse Server directly instead of via the HTTP interface. Default is `false`.

If set to `false` then Parse requests within the same Node.js environment as Parse Server are executed as HTTP requests sent to Parse Server via the `serverURL`. For example, a `Parse.Query` in Cloud Code is calling Parse Server via a HTTP request. The server is essentially making a HTTP request to itself, unnecessarily using network resources such as network ports.

⚠️ In environments where multiple Parse Server instances run behind a load balancer and Parse requests within the current Node.js environment should be routed via the load balancer and distributed as HTTP requests among all instances via the `serverURL`, this should be set to `false`. * @property {String} dotNetKey Key for Unity and .Net SDK * @property {Adapter} emailAdapter Adapter module for email sending diff --git a/src/Options/index.js b/src/Options/index.js index 6fbe4566aa..d4a9027b2a 100644 --- a/src/Options/index.js +++ b/src/Options/index.js @@ -286,9 +286,6 @@ export interface ParseServerOptions { /* An array of keys and values that are prohibited in database read and write requests to prevent potential security vulnerabilities. It is possible to specify only a key (`{"key":"..."}`), only a value (`{"value":"..."}`) or a key-value pair (`{"key":"...","value":"..."}`). The specification can use the following types: `boolean`, `numeric` or `string`, where `string` will be interpreted as a regex notation. Request data is deep-scanned for matching definitions to detect also any nested occurrences. Defaults are patterns that are likely to be used in malicious requests. Setting this option will override the default patterns. :DEFAULT: [{"key":"_bsontype","value":"Code"},{"key":"constructor"},{"key":"__proto__"}] */ requestKeywordDenylist: ?(RequestKeywordDenylist[]); - /* Value for Parse Server's `dns.setDefaultResultOrder` - [NodeJS' DNS lookup](https://nodejs.org/api/dns.html#dnssetdefaultresultorderorder) - :DEFAULT: verbatim */ - defaultResultOrder: ?string; } export interface SecurityOptions { diff --git a/src/ParseServer.js b/src/ParseServer.js index 864409135d..b1905da202 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -95,7 +95,7 @@ class ParseServer { security, schema, cacheAdapter, - liveQueryController + liveQueryController, } = this.config; try { await databaseController.performInitialization(); diff --git a/src/Routers/PagesRouter.js b/src/Routers/PagesRouter.js index 5d5a1467a7..6e6ba8a8fd 100644 --- a/src/Routers/PagesRouter.js +++ b/src/Routers/PagesRouter.js @@ -236,15 +236,15 @@ export class PagesRouter extends PromiseRouter { const query = result.success ? { - [pageParams.username]: username, - } + [pageParams.username]: username, + } : { - [pageParams.username]: username, - [pageParams.token]: token, - [pageParams.appId]: config.applicationId, - [pageParams.error]: result.err, - [pageParams.appName]: config.appName, - }; + [pageParams.username]: username, + [pageParams.token]: token, + [pageParams.appId]: config.applicationId, + [pageParams.error]: result.err, + [pageParams.appName]: config.appName, + }; const page = result.success ? pages.passwordResetSuccess : pages.passwordReset; return this.goToPage(req, page, query, false); @@ -273,8 +273,8 @@ export class PagesRouter extends PromiseRouter { const redirect = config.pages.forceRedirect ? true : responseType !== undefined - ? responseType - : req.method == 'POST'; + ? responseType + : req.method == 'POST'; // Include default parameters const defaultParams = this.getDefaultParams(config); @@ -311,9 +311,9 @@ export class PagesRouter extends PromiseRouter { return Utils.getLocalizedPath(defaultPath, locale).then(({ path, subdir }) => redirect ? this.redirectResponse( - this.composePageUrl(defaultFile, config.publicServerURL, subdir), - params - ) + this.composePageUrl(defaultFile, config.publicServerURL, subdir), + params + ) : this.pageResponse(path, params, placeholders) ); } else { @@ -452,8 +452,8 @@ export class PagesRouter extends PromiseRouter { typeof this.pagesConfig.placeholders === 'function' ? this.pagesConfig.placeholders(params) : Object.prototype.toString.call(this.pagesConfig.placeholders) === '[object Object]' - ? this.pagesConfig.placeholders - : {}; + ? this.pagesConfig.placeholders + : {}; if (configPlaceholders instanceof Promise) { configPlaceholders = await configPlaceholders; } @@ -543,10 +543,10 @@ export class PagesRouter extends PromiseRouter { getDefaultParams(config) { return config ? { - [pageParams.appId]: config.appId, - [pageParams.appName]: config.appName, - [pageParams.publicServerUrl]: config.publicServerURL, - } + [pageParams.appId]: config.appId, + [pageParams.appName]: config.appName, + [pageParams.publicServerUrl]: config.publicServerURL, + } : {}; } diff --git a/src/batch.js b/src/batch.js index ca7adddc91..34dd8d6a28 100644 --- a/src/batch.js +++ b/src/batch.js @@ -48,8 +48,8 @@ function makeBatchRoutingPathFunction(originalUrl, serverURL, publicServerURL) { startsWithLocal && startsWithPublic ? Math.max(localPath.length, publicPath.length) : startsWithLocal - ? localPath.length - : publicPath.length; + ? localPath.length + : publicPath.length; const newPath = path.posix.join('/', localPath, '/', requestPath.slice(pathLengthToUse)); diff --git a/src/cli/parse-server.js b/src/cli/parse-server.js index 79274e6893..b0c574bfea 100755 --- a/src/cli/parse-server.js +++ b/src/cli/parse-server.js @@ -4,7 +4,6 @@ import definitions from './definitions/parse-server'; import cluster from 'cluster'; import os from 'os'; import runner from './utils/runner'; -import dns from 'dns'; const help = function () { console.log(' Get Started guide:'); @@ -41,10 +40,6 @@ runner({ process.exit(1); } - if (options.defaultResultOrder && dns.setDefaultResultOrder) { - dns.setDefaultResultOrder(options.defaultResultOrder); - } - if (options['liveQuery.classNames']) { options.liveQuery = options.liveQuery || {}; options.liveQuery.classNames = options['liveQuery.classNames']; From 0f83fdd07e7383a339ff2ddf60d653c52ac9884d Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 27 Nov 2022 12:56:06 +1100 Subject: [PATCH 078/104] wip --- README.md | 15 +++++++-------- spec/support/FailingServer.js | 32 +++++++++++++++----------------- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 2d44f4b59b..8de666eced 100644 --- a/README.md +++ b/README.md @@ -875,14 +875,13 @@ app.use('/parse', parseServer.app); // (Optional) Mounts the REST API parseGraphQLServer.applyGraphQL(app); // Mounts the GraphQL API parseGraphQLServer.applyPlayground(app); // (Optional) Mounts the GraphQL Playground - do NOT use in Production -(async () => { - await parseServer.start(); - app.listen(1337, function() { - console.log('REST API running on http://localhost:1337/parse'); - console.log('GraphQL API running on http://localhost:1337/graphql'); - console.log('GraphQL Playground running on http://localhost:1337/playground'); - }); -})(); +await parseServer.start(); +app.listen(1337, function() { + console.log('REST API running on http://localhost:1337/parse'); + console.log('GraphQL API running on http://localhost:1337/graphql'); + console.log('GraphQL Playground running on http://localhost:1337/playground'); +}); + ``` And finally start your app: diff --git a/spec/support/FailingServer.js b/spec/support/FailingServer.js index 60112ae82c..ba9d635b8d 100755 --- a/spec/support/FailingServer.js +++ b/spec/support/FailingServer.js @@ -6,20 +6,18 @@ const ParseServer = require('../../lib/index').ParseServer; const databaseURI = 'mongodb://doesnotexist:27017/parseServerMongoAdapterTestDatabase'; -(async () => { - try { - await ParseServer.startApp({ - appId: 'test', - masterKey: 'test', - databaseAdapter: new MongoStorageAdapter({ - uri: databaseURI, - mongoOptions: { - serverSelectionTimeoutMS: 2000, - }, - }), - filesAdapter: new GridFSBucketAdapter(databaseURI), - }); - } catch (e) { - process.exit(1); - } -})(); +try { + await ParseServer.startApp({ + appId: 'test', + masterKey: 'test', + databaseAdapter: new MongoStorageAdapter({ + uri: databaseURI, + mongoOptions: { + serverSelectionTimeoutMS: 2000, + }, + }), + filesAdapter: new GridFSBucketAdapter(databaseURI), + }); +} catch (e) { + process.exit(1); +} From 7966601b2f78c9e969a8ad46fb72132591ffa278 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 27 Nov 2022 12:59:10 +1100 Subject: [PATCH 079/104] lint --- README.md | 1 - src/Deprecator/Deprecator.js | 4 ++-- src/Routers/PagesRouter.js | 38 ++++++++++++++++++------------------ src/batch.js | 4 ++-- 4 files changed, 23 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 8de666eced..2bac52b114 100644 --- a/README.md +++ b/README.md @@ -881,7 +881,6 @@ app.listen(1337, function() { console.log('GraphQL API running on http://localhost:1337/graphql'); console.log('GraphQL Playground running on http://localhost:1337/playground'); }); - ``` And finally start your app: diff --git a/src/Deprecator/Deprecator.js b/src/Deprecator/Deprecator.js index ed008230b0..27033c946d 100644 --- a/src/Deprecator/Deprecator.js +++ b/src/Deprecator/Deprecator.js @@ -101,8 +101,8 @@ class Deprecator { changeNewKey == null ? undefined : changeNewKey.length > 0 - ? `renamed to '${changeNewKey}'` - : `removed`; + ? `renamed to '${changeNewKey}'` + : `removed`; // Compose message let output = `DeprecationWarning: The Parse Server ${type} '${key}' `; diff --git a/src/Routers/PagesRouter.js b/src/Routers/PagesRouter.js index 6e6ba8a8fd..5d5a1467a7 100644 --- a/src/Routers/PagesRouter.js +++ b/src/Routers/PagesRouter.js @@ -236,15 +236,15 @@ export class PagesRouter extends PromiseRouter { const query = result.success ? { - [pageParams.username]: username, - } + [pageParams.username]: username, + } : { - [pageParams.username]: username, - [pageParams.token]: token, - [pageParams.appId]: config.applicationId, - [pageParams.error]: result.err, - [pageParams.appName]: config.appName, - }; + [pageParams.username]: username, + [pageParams.token]: token, + [pageParams.appId]: config.applicationId, + [pageParams.error]: result.err, + [pageParams.appName]: config.appName, + }; const page = result.success ? pages.passwordResetSuccess : pages.passwordReset; return this.goToPage(req, page, query, false); @@ -273,8 +273,8 @@ export class PagesRouter extends PromiseRouter { const redirect = config.pages.forceRedirect ? true : responseType !== undefined - ? responseType - : req.method == 'POST'; + ? responseType + : req.method == 'POST'; // Include default parameters const defaultParams = this.getDefaultParams(config); @@ -311,9 +311,9 @@ export class PagesRouter extends PromiseRouter { return Utils.getLocalizedPath(defaultPath, locale).then(({ path, subdir }) => redirect ? this.redirectResponse( - this.composePageUrl(defaultFile, config.publicServerURL, subdir), - params - ) + this.composePageUrl(defaultFile, config.publicServerURL, subdir), + params + ) : this.pageResponse(path, params, placeholders) ); } else { @@ -452,8 +452,8 @@ export class PagesRouter extends PromiseRouter { typeof this.pagesConfig.placeholders === 'function' ? this.pagesConfig.placeholders(params) : Object.prototype.toString.call(this.pagesConfig.placeholders) === '[object Object]' - ? this.pagesConfig.placeholders - : {}; + ? this.pagesConfig.placeholders + : {}; if (configPlaceholders instanceof Promise) { configPlaceholders = await configPlaceholders; } @@ -543,10 +543,10 @@ export class PagesRouter extends PromiseRouter { getDefaultParams(config) { return config ? { - [pageParams.appId]: config.appId, - [pageParams.appName]: config.appName, - [pageParams.publicServerUrl]: config.publicServerURL, - } + [pageParams.appId]: config.appId, + [pageParams.appName]: config.appName, + [pageParams.publicServerUrl]: config.publicServerURL, + } : {}; } diff --git a/src/batch.js b/src/batch.js index 34dd8d6a28..ca7adddc91 100644 --- a/src/batch.js +++ b/src/batch.js @@ -48,8 +48,8 @@ function makeBatchRoutingPathFunction(originalUrl, serverURL, publicServerURL) { startsWithLocal && startsWithPublic ? Math.max(localPath.length, publicPath.length) : startsWithLocal - ? localPath.length - : publicPath.length; + ? localPath.length + : publicPath.length; const newPath = path.posix.join('/', localPath, '/', requestPath.slice(pathLengthToUse)); From 6546087f9bf26befd20845e2cda77f47e093989c Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 27 Nov 2022 16:21:20 +1100 Subject: [PATCH 080/104] Update README.md --- README.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 2bac52b114..49377b9318 100644 --- a/README.md +++ b/README.md @@ -282,11 +282,11 @@ We have provided a basic [Node.js application](https://github.com/parse-communit You can also create an instance of Parse Server, and mount it on a new or existing Express website: ```js -var express = require('express'); -var ParseServer = require('parse-server').ParseServer; -var app = express(); +const express = require('express'); +const ParseServer = require('parse-server').ParseServer; +const app = express(); -var api = new ParseServer({ +const api = new ParseServer({ databaseURI: 'mongodb://localhost:27017/dev', // Connection string for your MongoDB database cloud: './cloud/main.js', // Path to your Cloud Code appId: 'myAppId', @@ -295,6 +295,9 @@ var api = new ParseServer({ serverURL: 'http://localhost:1337/parse' // Don't forget to change to https if needed }); +// start the API +await api.start(); + // Serve the Parse API on the /parse URL prefix app.use('/parse', api); @@ -461,7 +464,7 @@ The following paths are already used by Parse Server's built-in features and are It’s possible to change the default pages of the app and redirect the user to another path or domain. ```js -var server = ParseServer({ +const server = ParseServer({ ...otherOptions, customPages: { From 147966b843336c11eadc3150980e43449a514b78 Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 27 Nov 2022 16:36:26 +1100 Subject: [PATCH 081/104] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 49377b9318..921b0a6f0c 100644 --- a/README.md +++ b/README.md @@ -299,7 +299,7 @@ const api = new ParseServer({ await api.start(); // Serve the Parse API on the /parse URL prefix -app.use('/parse', api); +app.use('/parse', api.app); app.listen(1337, function() { console.log('parse-server-example running on port 1337.'); From 1ec6b51ace9d40df5a4c8a72038b0f333d0c711f Mon Sep 17 00:00:00 2001 From: dblythy Date: Sun, 27 Nov 2022 18:56:39 +1100 Subject: [PATCH 082/104] push --- spec/support/FailingServer.js | 32 +++++++++++++++++--------------- src/ParseServer.js | 2 +- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/spec/support/FailingServer.js b/spec/support/FailingServer.js index ba9d635b8d..60112ae82c 100755 --- a/spec/support/FailingServer.js +++ b/spec/support/FailingServer.js @@ -6,18 +6,20 @@ const ParseServer = require('../../lib/index').ParseServer; const databaseURI = 'mongodb://doesnotexist:27017/parseServerMongoAdapterTestDatabase'; -try { - await ParseServer.startApp({ - appId: 'test', - masterKey: 'test', - databaseAdapter: new MongoStorageAdapter({ - uri: databaseURI, - mongoOptions: { - serverSelectionTimeoutMS: 2000, - }, - }), - filesAdapter: new GridFSBucketAdapter(databaseURI), - }); -} catch (e) { - process.exit(1); -} +(async () => { + try { + await ParseServer.startApp({ + appId: 'test', + masterKey: 'test', + databaseAdapter: new MongoStorageAdapter({ + uri: databaseURI, + mongoOptions: { + serverSelectionTimeoutMS: 2000, + }, + }), + filesAdapter: new GridFSBucketAdapter(databaseURI), + }); + } catch (e) { + process.exit(1); + } +})(); diff --git a/src/ParseServer.js b/src/ParseServer.js index b1905da202..fd9b160e40 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -280,7 +280,7 @@ class ParseServer { try { await this.start(); } catch (e) { - console.error('Error on ParseServer.start: ', e); + console.error('Error on ParseServer.startApp: ', e); throw e; } const app = express(); From 8c5d223e5bd4ebe6cc506bf45eb83062d597f5eb Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 28 Nov 2022 10:22:47 +1100 Subject: [PATCH 083/104] Update README.md Co-authored-by: Manuel <5673677+mtrezza@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 921b0a6f0c..07d1475b43 100644 --- a/README.md +++ b/README.md @@ -286,7 +286,7 @@ const express = require('express'); const ParseServer = require('parse-server').ParseServer; const app = express(); -const api = new ParseServer({ +const server = new ParseServer({ databaseURI: 'mongodb://localhost:27017/dev', // Connection string for your MongoDB database cloud: './cloud/main.js', // Path to your Cloud Code appId: 'myAppId', From 26c87f97f245343346fd286efb660252d710b0b1 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 28 Nov 2022 10:22:56 +1100 Subject: [PATCH 084/104] Update README.md Co-authored-by: Manuel <5673677+mtrezza@users.noreply.github.com> --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 07d1475b43..c665943f6c 100644 --- a/README.md +++ b/README.md @@ -295,8 +295,8 @@ const server = new ParseServer({ serverURL: 'http://localhost:1337/parse' // Don't forget to change to https if needed }); -// start the API -await api.start(); +// Start server +await server.start(); // Serve the Parse API on the /parse URL prefix app.use('/parse', api.app); From 5623ff4bcfb339bba52c0ce74dfe30a1434862a8 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 28 Nov 2022 10:23:06 +1100 Subject: [PATCH 085/104] Update README.md Co-authored-by: Manuel <5673677+mtrezza@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c665943f6c..ed528eca60 100644 --- a/README.md +++ b/README.md @@ -299,7 +299,7 @@ const server = new ParseServer({ await server.start(); // Serve the Parse API on the /parse URL prefix -app.use('/parse', api.app); +app.use('/parse', server.app); app.listen(1337, function() { console.log('parse-server-example running on port 1337.'); From 4d30eda415b315e39772762b77ae6da33cb79d4b Mon Sep 17 00:00:00 2001 From: Manuel Trezza <5673677+mtrezza@users.noreply.github.com> Date: Mon, 28 Nov 2022 02:08:26 +0100 Subject: [PATCH 086/104] add readme docs --- README.md | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ed528eca60..dcf4275b46 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ A big *thank you* πŸ™ to our [sponsors](#sponsors) and [backers](#backers) who --- -- [Flavors & Branches](#flavors--branches) +- [Flavors \& Branches](#flavors--branches) - [Long Term Support](#long-term-support) - [Getting Started](#getting-started) - [Running Parse Server](#running-parse-server) @@ -55,6 +55,8 @@ A big *thank you* πŸ™ to our [sponsors](#sponsors) and [backers](#backers) who - [Running Parse Server elsewhere](#running-parse-server-elsewhere) - [Sample Application](#sample-application) - [Parse Server + Express](#parse-server--express) + - [Parse Server Health](#parse-server-health) + - [Status Values](#status-values) - [Configuration](#configuration) - [Basic Options](#basic-options) - [Client Key Options](#client-key-options) @@ -136,13 +138,13 @@ Parse Server is continuously tested with the most recent releases of Node.js to 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. We consider the end-of-life date of a MongoDB "rapid release" to be the same as its major version release. -| Version | Latest Version | End-of-Life | Compatible | -|-------------|----------------|---------------|--------------| -| MongoDB 4.0 | 4.0.28 | April 2022 | βœ… Yes | -| MongoDB 4.2 | 4.2.19 | April 2023 | βœ… Yes | -| MongoDB 4.4 | 4.4.13 | February 2024 | βœ… Yes | -| MongoDB 5 | 5.3.2 | October 2024 | βœ… Yes | -| MongoDB 6 | 6.0.2 | July 2025 | βœ… Yes | +| Version | Latest Version | End-of-Life | Compatible | +|-------------|----------------|---------------|------------| +| MongoDB 4.0 | 4.0.28 | April 2022 | βœ… Yes | +| MongoDB 4.2 | 4.2.19 | April 2023 | βœ… Yes | +| MongoDB 4.4 | 4.4.13 | February 2024 | βœ… Yes | +| MongoDB 5 | 5.3.2 | October 2024 | βœ… Yes | +| MongoDB 6 | 6.0.2 | July 2025 | βœ… Yes | #### PostgreSQL @@ -308,6 +310,27 @@ app.listen(1337, function() { For a full list of available options, run `parse-server --help` or take a look at [Parse Server Configurations](http://parseplatform.org/parse-server/api/master/ParseServerOptions.html). +## Parse Server Health + +Check the Parse Server health by sending a request to the `/parse/health` endpoint. + +The response looks like this: + +```json +{ + "status": "ok" +} +``` + +### Status Values + +| Value | Description | +|---------------|-----------------------------------------------------------------------------| +| `initialized` | The server has been created but the `start` method has not been called yet. | +| `starting` | The server is starting up. | +| `ok` | The server started and is running. | +| `error` | There was a startup error, see the logs for details. | + # Configuration Parse Server can be configured using the following options. You may pass these as parameters when running a standalone `parse-server`, or by loading a configuration file in JSON format using `parse-server path/to/configuration.json`. If you're using Parse Server on Express, you may also pass these to the `ParseServer` object as options. From 96412176ba1766da8f47144f10e0ff44fff21763 Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 28 Nov 2022 15:19:41 +1100 Subject: [PATCH 087/104] Update ParseServer.js --- src/ParseServer.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ParseServer.js b/src/ParseServer.js index fd9b160e40..fdcad869ee 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -119,8 +119,9 @@ class ParseServer { if (typeof cloud === 'function') { await Promise.resolve(cloud(Parse)); } else if (typeof cloud === 'string') { - if (process.env.npm_package_type === 'module') { - await import(path.resolve(process.cwd(), cloud)); + const json = require(process.env.npm_package_json); + if (process.env.npm_package_type === 'module' || json.type === 'module') { + await import(path.resolve(process.cwd(), cloud)).default; } else { require(path.resolve(process.cwd(), cloud)); } From 8bc829015996d8209e11c09ae2475e3e2a9e5e18 Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 28 Nov 2022 16:07:22 +1100 Subject: [PATCH 088/104] Update ParseServer.js --- src/ParseServer.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ParseServer.js b/src/ParseServer.js index fdcad869ee..3efca181e8 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -45,6 +45,7 @@ import { SecurityRouter } from './Routers/SecurityRouter'; import CheckRunner from './Security/CheckRunner'; import Deprecator from './Deprecator/Deprecator'; import { DefinedSchemas } from './SchemaMigrations/DefinedSchemas'; +import { nextTick } from 'process'; // Mutate the Parse object to add the Cloud Code handlers addParseCloud(); @@ -122,6 +123,7 @@ class ParseServer { const json = require(process.env.npm_package_json); if (process.env.npm_package_type === 'module' || json.type === 'module') { await import(path.resolve(process.cwd(), cloud)).default; + await new Promise(resolve => nextTick(resolve)); } else { require(path.resolve(process.cwd(), cloud)); } From 90cc6163b359e98fb2fdc43774f5dbf69a0ef06a Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 28 Nov 2022 16:32:32 +1100 Subject: [PATCH 089/104] Update ParseServer.js --- src/ParseServer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ParseServer.js b/src/ParseServer.js index 3efca181e8..6911c1ac9c 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -123,7 +123,7 @@ class ParseServer { const json = require(process.env.npm_package_json); if (process.env.npm_package_type === 'module' || json.type === 'module') { await import(path.resolve(process.cwd(), cloud)).default; - await new Promise(resolve => nextTick(resolve)); + await new Promise(resolve => setTimeout(resolve, 10)); } else { require(path.resolve(process.cwd(), cloud)); } From f9adde8026fadbf4e28434205d19071a2bd44135 Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 28 Nov 2022 16:41:51 +1100 Subject: [PATCH 090/104] test --- spec/CloudCode.spec.js | 2 +- src/ParseServer.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index d663698875..5dac71dcb5 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -40,7 +40,7 @@ describe('Cloud Code', () => { }); }); - it('can load cloud code as a module', async () => { + fit('can load cloud code as a module', async () => { process.env.npm_package_type = 'module'; await reconfigureServer({ cloud: './spec/cloud/cloudCodeModuleFile.js' }); const result = await Parse.Cloud.run('cloudCodeInFile'); diff --git a/src/ParseServer.js b/src/ParseServer.js index 6911c1ac9c..776ef09c00 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -120,6 +120,7 @@ class ParseServer { if (typeof cloud === 'function') { await Promise.resolve(cloud(Parse)); } else if (typeof cloud === 'string') { + console.log(process.env.npm_package_json); const json = require(process.env.npm_package_json); if (process.env.npm_package_type === 'module' || json.type === 'module') { await import(path.resolve(process.cwd(), cloud)).default; From 0471e60ff91772ebed9ce1339884ae8dd49819a4 Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 28 Nov 2022 16:44:55 +1100 Subject: [PATCH 091/104] wip --- spec/CloudCode.spec.js | 2 +- src/ParseServer.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index 5dac71dcb5..c737a82727 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -42,7 +42,7 @@ describe('Cloud Code', () => { fit('can load cloud code as a module', async () => { process.env.npm_package_type = 'module'; - await reconfigureServer({ cloud: './spec/cloud/cloudCodeModuleFile.js' }); + await reconfigureServer({ cloud: './spec/cloud/cloudCodeModuleFile.js', silent: false }); const result = await Parse.Cloud.run('cloudCodeInFile'); expect(result).toEqual('It is possible to define cloud code in a file.'); delete process.env.npm_package_type; diff --git a/src/ParseServer.js b/src/ParseServer.js index 776ef09c00..f5454932ea 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -120,7 +120,7 @@ class ParseServer { if (typeof cloud === 'function') { await Promise.resolve(cloud(Parse)); } else if (typeof cloud === 'string') { - console.log(process.env.npm_package_json); + console.log(process.env); const json = require(process.env.npm_package_json); if (process.env.npm_package_type === 'module' || json.type === 'module') { await import(path.resolve(process.cwd(), cloud)).default; From c5bcc2b288abb226e2557526c49c2d9935013d14 Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 28 Nov 2022 16:55:49 +1100 Subject: [PATCH 092/104] wip --- spec/CloudCode.spec.js | 4 ++-- spec/cloud/cloudCodeModuleFile.js | 3 --- src/ParseServer.js | 10 ++++++---- 3 files changed, 8 insertions(+), 9 deletions(-) delete mode 100644 spec/cloud/cloudCodeModuleFile.js diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index c737a82727..1b929809fe 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -40,9 +40,9 @@ describe('Cloud Code', () => { }); }); - fit('can load cloud code as a module', async () => { + it('can load cloud code as a module', async () => { process.env.npm_package_type = 'module'; - await reconfigureServer({ cloud: './spec/cloud/cloudCodeModuleFile.js', silent: false }); + await reconfigureServer({ appId: 'test1', cloud: './spec/cloud/cloudCodeAbsoluteFile.js' }); const result = await Parse.Cloud.run('cloudCodeInFile'); expect(result).toEqual('It is possible to define cloud code in a file.'); delete process.env.npm_package_type; diff --git a/spec/cloud/cloudCodeModuleFile.js b/spec/cloud/cloudCodeModuleFile.js deleted file mode 100644 index a62b4fcc24..0000000000 --- a/spec/cloud/cloudCodeModuleFile.js +++ /dev/null @@ -1,3 +0,0 @@ -Parse.Cloud.define('cloudCodeInFile', () => { - return 'It is possible to define cloud code in a file.'; -}); diff --git a/src/ParseServer.js b/src/ParseServer.js index f5454932ea..066571357a 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -120,11 +120,13 @@ class ParseServer { if (typeof cloud === 'function') { await Promise.resolve(cloud(Parse)); } else if (typeof cloud === 'string') { - console.log(process.env); - const json = require(process.env.npm_package_json); - if (process.env.npm_package_type === 'module' || json.type === 'module') { + let json; + if (process.env.npm_package_json) { + json = require(process.env.npm_package_json); + } + if (process.env.npm_package_type === 'module' || json?.type === 'module') { await import(path.resolve(process.cwd(), cloud)).default; - await new Promise(resolve => setTimeout(resolve, 10)); + await new Promise(resolve => nextTick(resolve)); } else { require(path.resolve(process.cwd(), cloud)); } From 840e667fc6ffea760fb0c191c95653270538827e Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 28 Nov 2022 17:04:35 +1100 Subject: [PATCH 093/104] change --- spec/CloudCode.spec.js | 2 +- src/ParseServer.js | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index 1b929809fe..e154d29bd0 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -40,7 +40,7 @@ describe('Cloud Code', () => { }); }); - it('can load cloud code as a module', async () => { + fit('can load cloud code as a module', async () => { process.env.npm_package_type = 'module'; await reconfigureServer({ appId: 'test1', cloud: './spec/cloud/cloudCodeAbsoluteFile.js' }); const result = await Parse.Cloud.run('cloudCodeInFile'); diff --git a/src/ParseServer.js b/src/ParseServer.js index 066571357a..a1ddde4def 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -125,8 +125,11 @@ class ParseServer { json = require(process.env.npm_package_json); } if (process.env.npm_package_type === 'module' || json?.type === 'module') { + console.log('a') await import(path.resolve(process.cwd(), cloud)).default; - await new Promise(resolve => nextTick(resolve)); + console.log('b') + await new Promise(resolve => setTimeout(resolve, 100)); + console.log('c') } else { require(path.resolve(process.cwd(), cloud)); } From f8019db657cfc054d506199e2e1e04edd9d47c65 Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 28 Nov 2022 17:07:57 +1100 Subject: [PATCH 094/104] wip --- spec/CloudCode.spec.js | 2 +- src/ParseServer.js | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index e154d29bd0..1b929809fe 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -40,7 +40,7 @@ describe('Cloud Code', () => { }); }); - fit('can load cloud code as a module', async () => { + it('can load cloud code as a module', async () => { process.env.npm_package_type = 'module'; await reconfigureServer({ appId: 'test1', cloud: './spec/cloud/cloudCodeAbsoluteFile.js' }); const result = await Parse.Cloud.run('cloudCodeInFile'); diff --git a/src/ParseServer.js b/src/ParseServer.js index a1ddde4def..b4d5bef4f8 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -45,7 +45,6 @@ import { SecurityRouter } from './Routers/SecurityRouter'; import CheckRunner from './Security/CheckRunner'; import Deprecator from './Deprecator/Deprecator'; import { DefinedSchemas } from './SchemaMigrations/DefinedSchemas'; -import { nextTick } from 'process'; // Mutate the Parse object to add the Cloud Code handlers addParseCloud(); @@ -125,11 +124,8 @@ class ParseServer { json = require(process.env.npm_package_json); } if (process.env.npm_package_type === 'module' || json?.type === 'module') { - console.log('a') await import(path.resolve(process.cwd(), cloud)).default; - console.log('b') await new Promise(resolve => setTimeout(resolve, 100)); - console.log('c') } else { require(path.resolve(process.cwd(), cloud)); } From 7d7a77a4621f50b1045b7df53a45b2c06a5f0491 Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 28 Nov 2022 17:22:05 +1100 Subject: [PATCH 095/104] module file --- spec/CloudCode.spec.js | 2 +- spec/cloud/cloudCodeModuleFile.js | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 spec/cloud/cloudCodeModuleFile.js diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index 1b929809fe..89bc3fdaa0 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -42,7 +42,7 @@ describe('Cloud Code', () => { it('can load cloud code as a module', async () => { process.env.npm_package_type = 'module'; - await reconfigureServer({ appId: 'test1', cloud: './spec/cloud/cloudCodeAbsoluteFile.js' }); + await reconfigureServer({ appId: 'test1', cloud: './spec/cloud/cloudCodeModuleFile.js' }); const result = await Parse.Cloud.run('cloudCodeInFile'); expect(result).toEqual('It is possible to define cloud code in a file.'); delete process.env.npm_package_type; diff --git a/spec/cloud/cloudCodeModuleFile.js b/spec/cloud/cloudCodeModuleFile.js new file mode 100644 index 0000000000..a62b4fcc24 --- /dev/null +++ b/spec/cloud/cloudCodeModuleFile.js @@ -0,0 +1,3 @@ +Parse.Cloud.define('cloudCodeInFile', () => { + return 'It is possible to define cloud code in a file.'; +}); From 10ee837ec9e63cce7a5c274d9f97057499a59ce7 Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 28 Nov 2022 17:32:26 +1100 Subject: [PATCH 096/104] Update ParseServer.js --- src/ParseServer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ParseServer.js b/src/ParseServer.js index b4d5bef4f8..bef18ec6e7 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -125,13 +125,13 @@ class ParseServer { } if (process.env.npm_package_type === 'module' || json?.type === 'module') { await import(path.resolve(process.cwd(), cloud)).default; - await new Promise(resolve => setTimeout(resolve, 100)); } else { require(path.resolve(process.cwd(), cloud)); } } else { throw "argument 'cloud' must either be a string or a function"; } + await new Promise(resolve => setTimeout(resolve, 10)); } if (security && security.enableCheck && security.enableCheckLog) { new CheckRunner(security).run(); From a3f481f876a65f82f0169d9a657514d59e5e55ca Mon Sep 17 00:00:00 2001 From: Manuel Trezza <5673677+mtrezza@users.noreply.github.com> Date: Thu, 8 Dec 2022 21:52:27 +0100 Subject: [PATCH 097/104] add migration guide --- 6.0.0.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 6.0.0.md diff --git a/6.0.0.md b/6.0.0.md new file mode 100644 index 0000000000..22f5b8a650 --- /dev/null +++ b/6.0.0.md @@ -0,0 +1,28 @@ +# Parse Server 6 Migration Guide + +This document only highlights specific changes that require a longer explanation. For a full list of changes in Parse Server 6 please refer to the [changelog](https://github.com/parse-community/parse-server/blob/alpha/CHANGELOG.md). + +--- + +- [Asynchronous Initialization](#asynchronous-initialization) + +--- + +## Asynchronous Initialization + +Previously, it was possible to mount Parse Server before it was fully started up and ready to receive requests. This could result in undefined behavior, such as Parse Objects could be saved before Cloud Code was registered. To prevent this, Parse Server 6 requires to be started asynchronously before being mounted. + +*Parse Server 5:* +```js +const ParseServer = require('parse-server'); +const server = new ParseServer(config); +app.use("/parse", server); +``` + +*Parse Server 6:* +```js +const ParseServer = require('parse-server'); +const server = new ParseServer(config); +await server.start(); // Starts Parse Server and returns only after it's fully started up +app.use("/parse", server.app); +``` From 1645b0772b0ad5a8bfdc05841325442b102d8f29 Mon Sep 17 00:00:00 2001 From: Manuel Trezza <5673677+mtrezza@users.noreply.github.com> Date: Thu, 8 Dec 2022 22:42:25 +0100 Subject: [PATCH 098/104] improve migration guide --- 6.0.0.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/6.0.0.md b/6.0.0.md index 22f5b8a650..0faf4bd62d 100644 --- a/6.0.0.md +++ b/6.0.0.md @@ -10,19 +10,33 @@ This document only highlights specific changes that require a longer explanation ## Asynchronous Initialization +The import and initialization syntax has been simplified with more intuitive naming and structure. + Previously, it was possible to mount Parse Server before it was fully started up and ready to receive requests. This could result in undefined behavior, such as Parse Objects could be saved before Cloud Code was registered. To prevent this, Parse Server 6 requires to be started asynchronously before being mounted. *Parse Server 5:* ```js -const ParseServer = require('parse-server'); +// 1. Import Parse Server +const { ParseServer } = require('parse-server'); + +// 2. Create a Parse Server instance as express middleware const server = new ParseServer(config); + +// 3. Mount express app app.use("/parse", server); ``` *Parse Server 6:* ```js +// 1. Import Parse Server const ParseServer = require('parse-server'); + +// 2. Create a Parse Server instance const server = new ParseServer(config); -await server.start(); // Starts Parse Server and returns only after it's fully started up + +// 3. Start up Parse Server asynchronously +await server.start(); + +// 4. Mount express app app.use("/parse", server.app); ``` From 24d493e9f30e106a520d1f8ea53d4965282ab39a Mon Sep 17 00:00:00 2001 From: Manuel Trezza <5673677+mtrezza@users.noreply.github.com> Date: Thu, 8 Dec 2022 22:42:56 +0100 Subject: [PATCH 099/104] fix migration guide typo --- 6.0.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/6.0.0.md b/6.0.0.md index 0faf4bd62d..75e709c716 100644 --- a/6.0.0.md +++ b/6.0.0.md @@ -37,6 +37,6 @@ const server = new ParseServer(config); // 3. Start up Parse Server asynchronously await server.start(); -// 4. Mount express app +// 4. Mount express middleware app.use("/parse", server.app); ``` From fcde18441fc5797eeb9605e27616f2b6038e4e6e Mon Sep 17 00:00:00 2001 From: Manuel Trezza <5673677+mtrezza@users.noreply.github.com> Date: Thu, 8 Dec 2022 23:43:07 +0100 Subject: [PATCH 100/104] migration typo fix --- 6.0.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/6.0.0.md b/6.0.0.md index 75e709c716..2fddac4725 100644 --- a/6.0.0.md +++ b/6.0.0.md @@ -22,7 +22,7 @@ const { ParseServer } = require('parse-server'); // 2. Create a Parse Server instance as express middleware const server = new ParseServer(config); -// 3. Mount express app +// 3. Mount express middleware app.use("/parse", server); ``` From ef739dbea85a371fc0c7f381ed2643ed46f08923 Mon Sep 17 00:00:00 2001 From: dblythy Date: Fri, 9 Dec 2022 12:23:07 +1100 Subject: [PATCH 101/104] Update 6.0.0.md --- 6.0.0.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/6.0.0.md b/6.0.0.md index 2fddac4725..5ceb17e0a9 100644 --- a/6.0.0.md +++ b/6.0.0.md @@ -14,6 +14,8 @@ The import and initialization syntax has been simplified with more intuitive nam Previously, it was possible to mount Parse Server before it was fully started up and ready to receive requests. This could result in undefined behavior, such as Parse Objects could be saved before Cloud Code was registered. To prevent this, Parse Server 6 requires to be started asynchronously before being mounted. +`new ParseServer` will always return a Parse Server instance. Previously, depending on where Parse Server was imported from, `new ParseServer` could return an express middleware. + *Parse Server 5:* ```js // 1. Import Parse Server From 6de7d89ad3240faa0d43170fa5c66036c44bb5cb Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Fri, 9 Dec 2022 17:03:06 +0100 Subject: [PATCH 102/104] Update 6.0.0.md Co-authored-by: Daniel --- 6.0.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/6.0.0.md b/6.0.0.md index 5ceb17e0a9..c88ba327e9 100644 --- a/6.0.0.md +++ b/6.0.0.md @@ -31,7 +31,7 @@ app.use("/parse", server); *Parse Server 6:* ```js // 1. Import Parse Server -const ParseServer = require('parse-server'); +const { ParseServer } = require('parse-server'); // 2. Create a Parse Server instance const server = new ParseServer(config); From 66286b2cfdf5cd2c7a73ca3a6950f4b2f5b6ec20 Mon Sep 17 00:00:00 2001 From: Manuel Trezza <5673677+mtrezza@users.noreply.github.com> Date: Sat, 10 Dec 2022 02:00:27 +0100 Subject: [PATCH 103/104] add import statement to migration --- 6.0.0.md | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/6.0.0.md b/6.0.0.md index c88ba327e9..31eefc0030 100644 --- a/6.0.0.md +++ b/6.0.0.md @@ -4,17 +4,36 @@ This document only highlights specific changes that require a longer explanation --- +- [Import Statement](#import-statement) - [Asynchronous Initialization](#asynchronous-initialization) --- -## Asynchronous Initialization +## Import Statement The import and initialization syntax has been simplified with more intuitive naming and structure. -Previously, it was possible to mount Parse Server before it was fully started up and ready to receive requests. This could result in undefined behavior, such as Parse Objects could be saved before Cloud Code was registered. To prevent this, Parse Server 6 requires to be started asynchronously before being mounted. +*Parse Server 5:* +```js +// Returns a Parse Server instance +const ParseServer = require('parse-server'); -`new ParseServer` will always return a Parse Server instance. Previously, depending on where Parse Server was imported from, `new ParseServer` could return an express middleware. +// Returns a Parse Server express middleware +const { ParseServer } = require('parse-server'); +``` + +*Parse Server 6:* +```js +// Both return a Parse Server instance +const ParseServer = require('parse-server'); +const { ParseServer } = require('parse-server'); +``` + +To get the express middleware in Parse Server 6, configure the Parse Server instance, start Parse Server and use its `app` property. See [Asynchronous Initialization](#asynchronous-initialization) for more details. + +## Asynchronous Initialization + +Previously, it was possible to mount Parse Server before it was fully started up and ready to receive requests. This could result in undefined behavior, such as Parse Objects could be saved before Cloud Code was registered. To prevent this, Parse Server 6 requires to be started asynchronously before being mounted. *Parse Server 5:* ```js @@ -31,7 +50,7 @@ app.use("/parse", server); *Parse Server 6:* ```js // 1. Import Parse Server -const { ParseServer } = require('parse-server'); +const ParseServer = require('parse-server'); // 2. Create a Parse Server instance const server = new ParseServer(config); From 69e4b90ec9cf7578dadb2cffda95d59eb9f5ee7e Mon Sep 17 00:00:00 2001 From: dblythy Date: Thu, 15 Dec 2022 12:37:07 +1100 Subject: [PATCH 104/104] add retry --- spec/index.spec.js | 13 ++++++++----- src/ParseServer.js | 4 ++++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/spec/index.spec.js b/spec/index.spec.js index 04b86b0152..9d99d6db31 100644 --- a/spec/index.spec.js +++ b/spec/index.spec.js @@ -545,13 +545,14 @@ describe('server', () => { ); const health = await request({ url: 'http://localhost:12701/parse/health', - }).then(res => res.data); - expect(health.status).toBe('initialized'); + }).catch(e => e); + expect(health.data.status).toBe('initialized'); + expect(health.status).toBe(503); await new Promise(resolve => server.close(resolve)); }); it('can get starting state', async () => { - await reconfigureServer({ appId: 'test2' }); + await reconfigureServer({ appId: 'test2', silent: false }); const parseServer = new ParseServer.ParseServer({ ...defaultConfiguration, appId: 'test2', @@ -568,8 +569,10 @@ describe('server', () => { const startingPromise = parseServer.start(); const health = await request({ url: 'http://localhost:12668/parse/health', - }).then(res => res.data); - expect(health.status).toBe('starting'); + }).catch(e => e); + expect(health.data.status).toBe('starting'); + expect(health.status).toBe(503); + expect(health.headers['retry-after']).toBe('1'); await startingPromise; await new Promise(resolve => server.close(resolve)); }); diff --git a/src/ParseServer.js b/src/ParseServer.js index bef18ec6e7..2d1a0f19f3 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -194,6 +194,10 @@ class ParseServer { ); api.use('/health', function (req, res) { + res.status(options.state === 'ok' ? 200 : 503); + if (options.state === 'starting') { + res.set('Retry-After', 1); + } res.json({ status: options.state, });