Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
"@graphql-tools/schema": "10.0.31",
"@graphql-tools/utils": "11.0.0",
"@parse/fs-files-adapter": "3.0.0",
"@parse/push-adapter": "8.4.0",
"bcryptjs": "3.0.3",
"commander": "14.0.3",
"cors": "2.8.6",
Expand Down Expand Up @@ -146,7 +145,8 @@
"parse-server": "bin/parse-server"
},
"optionalDependencies": {
"@node-rs/bcrypt": "1.10.7"
"@node-rs/bcrypt": "1.10.7",
"@parse/push-adapter": "8.4.0"
},
"collective": {
"type": "opencollective",
Expand Down
47 changes: 47 additions & 0 deletions spec/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const parseServerPackage = require('../package.json');
const MockEmailAdapterWithOptions = require('./support/MockEmailAdapterWithOptions');
const ParseServer = require('../lib/index');
const Config = require('../lib/Config');
const adapterLoader = require('../lib/Adapters/AdapterLoader');
const express = require('express');

const MongoStorageAdapter = require('../lib/Adapters/Storage/Mongo/MongoStorageAdapter').default;
Expand Down Expand Up @@ -211,6 +212,52 @@ describe('server', () => {
.catch(done.fail);
});

it('can start when push is not configured and optional push adapter is missing', async () => {
const originalLoadModule = adapterLoader.loadModule;
const loadModuleSpy = spyOn(adapterLoader, 'loadModule').and.callFake(modulePath => {
if (modulePath === '@parse/push-adapter') {
const error = new Error("Cannot find package '@parse/push-adapter'");
error.code = 'ERR_MODULE_NOT_FOUND';
return Promise.reject(error);
}
return originalLoadModule(modulePath);
});

try {
await reconfigureServer({
push: undefined,
});
const config = Config.get('test');
expect(config.hasPushSupport).toEqual(false);
} finally {
loadModuleSpy.and.callThrough();
}
});

it('throws clear error when push is configured and optional push adapter is missing', async () => {
const originalLoadModule = adapterLoader.loadModule;
const loadModuleSpy = spyOn(adapterLoader, 'loadModule').and.callFake(modulePath => {
if (modulePath === '@parse/push-adapter') {
const error = new Error("Cannot find package '@parse/push-adapter'");
error.code = 'ERR_MODULE_NOT_FOUND';
return Promise.reject(error);
}
return originalLoadModule(modulePath);
});

try {
await expectAsync(
reconfigureServer({
push: {},
})
).toBeRejectedWithError(
'Push is configured but the optional dependency "@parse/push-adapter" is not installed. Install "@parse/push-adapter" or configure "push.adapter".'
);
} finally {
loadModuleSpy.and.callThrough();
}
});

it('can properly sets the push support ', done => {
reconfigureServer({
push: {
Expand Down
23 changes: 21 additions & 2 deletions src/Controllers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,13 @@ interface PushControlling {
pushWorker: PushWorker;
}

function isPushAdapterModuleMissing(error: any): boolean {
const message = `${error?.message || error || ''}`;
const hasMissingCode =
error?.code === 'ERR_MODULE_NOT_FOUND' || error?.code === 'MODULE_NOT_FOUND';
return hasMissingCode && message.includes('@parse/push-adapter');
}

export async function getPushController(options: ParseServerOptions): PushControlling {
const { scheduledPush, push } = options;

Expand All @@ -179,7 +186,19 @@ export async function getPushController(options: ParseServerOptions): PushContro
}

// Pass the push options too as it works with the default
const ParsePushAdapter = await loadModule('@parse/push-adapter');
let ParsePushAdapter;
try {
ParsePushAdapter = await loadModule('@parse/push-adapter');
} catch (error) {
if (!isPushAdapterModuleMissing(error)) {
throw error;
}
if (push && !pushOptions.adapter) {
throw new Error(
'Push is configured but the optional dependency "@parse/push-adapter" is not installed. Install "@parse/push-adapter" or configure "push.adapter".'
);
}
}
const pushAdapter = loadAdapter(
pushOptions && pushOptions.adapter,
ParsePushAdapter,
Expand All @@ -195,7 +214,7 @@ export async function getPushController(options: ParseServerOptions): PushContro

const pushControllerQueue = new PushQueue(pushQueueOptions);
let pushWorker;
if (!disablePushWorker) {
if (!disablePushWorker && hasPushSupport) {
pushWorker = new PushWorker(pushAdapter, pushQueueOptions);
}
return {
Expand Down