From e128e8ea32f5b92571edfd496e5b3b249f01a3e3 Mon Sep 17 00:00:00 2001 From: andrew rumble Date: Wed, 25 Sep 2024 17:02:35 +0100 Subject: [PATCH] Convert app.js to ES modules GitOrigin-RevId: 7819cc8c8235b93b985c1c07c7dec778c93d9134 --- develop/docker-compose.dev.yml | 2 +- server-ce/runit/web-api-overleaf/run | 2 +- server-ce/runit/web-overleaf/run | 2 +- services/web/Dockerfile | 4 +- services/web/{app.js => app.mjs} | 60 +++++++++---------- services/web/bin/lint_flag_res_send_usage | 2 +- .../history-v1/test/acceptance/src/Init.js | 23 ------- .../history-v1/test/acceptance/src/Init.mjs | 22 +++++++ .../launchpad/test/acceptance/src/Init.js | 1 - .../launchpad/test/acceptance/src/Init.mjs | 1 + .../test/acceptance/src/Init.js | 14 ----- .../test/acceptance/src/Init.mjs | 14 +++++ services/web/package.json | 6 +- services/web/test/acceptance/src/Init.js | 42 ------------- services/web/test/acceptance/src/Init.mjs | 42 +++++++++++++ .../src/helpers/{InitApp.js => InitApp.mjs} | 30 +++++----- 16 files changed, 130 insertions(+), 137 deletions(-) rename services/web/{app.js => app.mjs} (59%) delete mode 100644 services/web/modules/history-v1/test/acceptance/src/Init.js create mode 100644 services/web/modules/history-v1/test/acceptance/src/Init.mjs delete mode 100644 services/web/modules/launchpad/test/acceptance/src/Init.js create mode 100644 services/web/modules/launchpad/test/acceptance/src/Init.mjs delete mode 100644 services/web/modules/server-ce-scripts/test/acceptance/src/Init.js create mode 100644 services/web/modules/server-ce-scripts/test/acceptance/src/Init.mjs delete mode 100644 services/web/test/acceptance/src/Init.js create mode 100644 services/web/test/acceptance/src/Init.mjs rename services/web/test/acceptance/src/helpers/{InitApp.js => InitApp.mjs} (76%) diff --git a/develop/docker-compose.dev.yml b/develop/docker-compose.dev.yml index 90ca30c7ca..4432a24162 100644 --- a/develop/docker-compose.dev.yml +++ b/develop/docker-compose.dev.yml @@ -120,7 +120,7 @@ services: - "127.0.0.1:9229:9229" volumes: - ../services/web/app:/overleaf/services/web/app - - ../services/web/app.js:/overleaf/services/web/app.js + - ../services/web/app.mjs:/overleaf/services/web/app.mjs - ../services/web/config:/overleaf/services/web/config - ../services/web/locales:/overleaf/services/web/locales - ../services/web/modules:/overleaf/services/web/modules diff --git a/server-ce/runit/web-api-overleaf/run b/server-ce/runit/web-api-overleaf/run index a2f1d0834d..9aafc53666 100755 --- a/server-ce/runit/web-api-overleaf/run +++ b/server-ce/runit/web-api-overleaf/run @@ -11,4 +11,4 @@ export LISTEN_ADDRESS=0.0.0.0 export ENABLED_SERVICES="api" export METRICS_APP_NAME="web-api" -exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /overleaf/services/web/app.js >> /var/log/overleaf/web-api.log 2>&1 +exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /overleaf/services/web/app.mjs >> /var/log/overleaf/web-api.log 2>&1 diff --git a/server-ce/runit/web-overleaf/run b/server-ce/runit/web-overleaf/run index 723e04d1ee..438328ad3a 100755 --- a/server-ce/runit/web-overleaf/run +++ b/server-ce/runit/web-overleaf/run @@ -11,4 +11,4 @@ export LISTEN_ADDRESS=127.0.0.1 export ENABLED_SERVICES="web" export WEB_PORT="4000" -exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /overleaf/services/web/app.js >> /var/log/overleaf/web.log 2>&1 +exec /sbin/setuser www-data /usr/bin/node $NODE_PARAMS /overleaf/services/web/app.mjs >> /var/log/overleaf/web.log 2>&1 diff --git a/services/web/Dockerfile b/services/web/Dockerfile index 58f53eb150..53a115715b 100644 --- a/services/web/Dockerfile +++ b/services/web/Dockerfile @@ -71,7 +71,7 @@ RUN OVERLEAF_CONFIG=/overleaf/services/web/config/settings.overrides.saas.js npm # the web image with only production dependencies but no webpack production build, for development FROM pug AS app-only USER node -CMD ["node", "--expose-gc", "app.js"] +CMD ["node", "--expose-gc", "app.mjs"] # the final production image, with webpack production build but without source maps @@ -80,4 +80,4 @@ ARG SENTRY_RELEASE ENV SENTRY_RELEASE=$SENTRY_RELEASE COPY --from=webpack-no-sourcemaps /overleaf/services/web/public /overleaf/services/web/public USER node -CMD ["node", "--expose-gc", "app.js"] +CMD ["node", "--expose-gc", "app.mjs"] diff --git a/services/web/app.js b/services/web/app.mjs similarity index 59% rename from services/web/app.js rename to services/web/app.mjs index 7fcae04db6..2b99f135f1 100644 --- a/services/web/app.js +++ b/services/web/app.mjs @@ -1,28 +1,34 @@ // Metrics must be initialized before importing anything else -require('@overleaf/metrics/initialize') +import '@overleaf/metrics/initialize.js' -const metrics = require('@overleaf/metrics') -const Settings = require('@overleaf/settings') -const logger = require('@overleaf/logger') -const PlansLocator = require('./app/src/Features/Subscription/PlansLocator') -const SiteAdminHandler = require('./app/src/infrastructure/SiteAdminHandler') -const Modules = require('./app/src/infrastructure/Modules') +import Modules from './app/src/infrastructure/Modules.js' +import metrics from '@overleaf/metrics' +import Settings from '@overleaf/settings' +import logger from '@overleaf/logger' +import PlansLocator from './app/src/Features/Subscription/PlansLocator.js' +import SiteAdminHandler from './app/src/infrastructure/SiteAdminHandler.js' + +import http from 'node:http' +import https from 'node:https' + +import * as Serializers from './app/src/infrastructure/LoggerSerializers.js' + +import Server from './app/src/infrastructure/Server.js' +import QueueWorkers from './app/src/infrastructure/QueueWorkers.js' +import mongodb from './app/src/infrastructure/mongodb.js' +import mongoose from './app/src/infrastructure/Mongoose.js' +import { triggerGracefulShutdown } from './app/src/infrastructure/GracefulShutdown.js' +import FileWriter from './app/src/infrastructure/FileWriter.js' +import { fileURLToPath } from 'url' logger.initialize(process.env.METRICS_APP_NAME || 'web') -logger.logger.serializers.user = - require('./app/src/infrastructure/LoggerSerializers').user -logger.logger.serializers.docs = - require('./app/src/infrastructure/LoggerSerializers').docs -logger.logger.serializers.files = - require('./app/src/infrastructure/LoggerSerializers').files -logger.logger.serializers.project = - require('./app/src/infrastructure/LoggerSerializers').project +logger.logger.serializers.user = Serializers.user +logger.logger.serializers.docs = Serializers.docs +logger.logger.serializers.files = Serializers.files +logger.logger.serializers.project = Serializers.project if (Settings.sentry?.dsn != null) { logger.initializeErrorReporting(Settings.sentry.dsn) } - -const http = require('http') -const https = require('https') http.globalAgent.maxSockets = Settings.limits.httpGlobalAgentMaxSockets https.globalAgent.maxSockets = Settings.limits.httpsGlobalAgentMaxSockets @@ -30,15 +36,6 @@ metrics.memory.monitor(logger) metrics.leaked_sockets.monitor(logger) metrics.open_sockets.monitor() -const Server = require('./app/src/infrastructure/Server') -const QueueWorkers = require('./app/src/infrastructure/QueueWorkers') -const mongodb = require('./app/src/infrastructure/mongodb') -const mongoose = require('./app/src/infrastructure/Mongoose') -const { - triggerGracefulShutdown, -} = require('./app/src/infrastructure/GracefulShutdown') -const FileWriter = require('./app/src/infrastructure/FileWriter') - if (Settings.catchErrors) { process.removeAllListeners('uncaughtException') process.on('uncaughtException', error => @@ -51,9 +48,8 @@ FileWriter.ensureDumpFolderExists() const port = Settings.port || Settings.internal.web.port || 3000 const host = Settings.internal.web.host || '127.0.0.1' -if (!module.parent) { +if (process.argv[1] === fileURLToPath(import.meta.url)) { // Called directly - // We want to make sure that we provided a password through the environment. if (!process.env.WEB_API_USER || !process.env.WEB_API_PASSWORD) { throw new Error('No API user and password provided') @@ -65,9 +61,7 @@ if (!module.parent) { .then(async () => { Server.server.listen(port, host, function () { logger.debug(`web starting up, listening on ${host}:${port}`) - logger.debug( - `${require('http').globalAgent.maxSockets} sockets enabled` - ) + logger.debug(`${http.globalAgent.maxSockets} sockets enabled`) // wait until the process is ready before monitoring the event loop metrics.event_loop.monitor(logger) }) @@ -93,4 +87,4 @@ process.on('SIGTERM', function (signal) { triggerGracefulShutdown(Server.server, signal) }) -module.exports = Server.server +export default Server.server diff --git a/services/web/bin/lint_flag_res_send_usage b/services/web/bin/lint_flag_res_send_usage index 763504de59..99310716fc 100755 --- a/services/web/bin/lint_flag_res_send_usage +++ b/services/web/bin/lint_flag_res_send_usage @@ -6,7 +6,7 @@ POTENTIAL_SEND_USAGE=$(\ grep \ --files-with-matches \ --recursive \ - app.js \ + app.mjs \ app/ \ modules/*/app \ test/acceptance/ \ diff --git a/services/web/modules/history-v1/test/acceptance/src/Init.js b/services/web/modules/history-v1/test/acceptance/src/Init.js deleted file mode 100644 index 743a69677c..0000000000 --- a/services/web/modules/history-v1/test/acceptance/src/Init.js +++ /dev/null @@ -1,23 +0,0 @@ -require('../../../../../test/acceptance/src/helpers/InitApp') - -const MockDocstoreApi = require('../../../../../test/acceptance/src/mocks/MockDocstoreApi') -const MockDocUpdaterApi = require('../../../../../test/acceptance/src/mocks/MockDocUpdaterApi') -const MockFilestoreApi = require('../../../../../test/acceptance/src/mocks/MockFilestoreApi') -const MockNotificationsApi = require('../../../../../test/acceptance/src/mocks/MockNotificationsApi') -const MockProjectHistoryApi = require('../../../../../test/acceptance/src/mocks/MockProjectHistoryApi') -const MockSpellingApi = require('../../../../../test/acceptance/src/mocks/MockSpellingApi') -const MockV1Api = require('../../../../../test/acceptance/src/mocks/MockV1Api') -const MockV1HistoryApi = require('../../../../../test/acceptance/src/mocks/MockV1HistoryApi') - -const mockOpts = { - debug: ['1', 'true', 'TRUE'].includes(process.env.DEBUG_MOCKS), -} - -MockDocstoreApi.initialize(23016, mockOpts) -MockDocUpdaterApi.initialize(23003, mockOpts) -MockFilestoreApi.initialize(23009, mockOpts) -MockNotificationsApi.initialize(23042, mockOpts) -MockProjectHistoryApi.initialize(23054, mockOpts) -MockSpellingApi.initialize(23005, mockOpts) -MockV1Api.initialize(25000, mockOpts) -MockV1HistoryApi.initialize(23100, mockOpts) diff --git a/services/web/modules/history-v1/test/acceptance/src/Init.mjs b/services/web/modules/history-v1/test/acceptance/src/Init.mjs new file mode 100644 index 0000000000..b79a9f6a3c --- /dev/null +++ b/services/web/modules/history-v1/test/acceptance/src/Init.mjs @@ -0,0 +1,22 @@ +import '../../../../../test/acceptance/src/helpers/InitApp.mjs' +import MockDocstoreApi from '../../../../../test/acceptance/src/mocks/MockDocstoreApi.js' +import MockDocUpdaterApi from '../../../../../test/acceptance/src/mocks/MockDocUpdaterApi.js' +import MockFilestoreApi from '../../../../../test/acceptance/src/mocks/MockFilestoreApi.js' +import MockNotificationsApi from '../../../../../test/acceptance/src/mocks/MockNotificationsApi.js' +import MockProjectHistoryApi from '../../../../../test/acceptance/src/mocks/MockProjectHistoryApi.js' +import MockSpellingApi from '../../../../../test/acceptance/src/mocks/MockSpellingApi.js' +import MockV1Api from '../../../../../test/acceptance/src/mocks/MockV1Api.js' +import MockV1HistoryApi from '../../../../../test/acceptance/src/mocks/MockV1HistoryApi.js' + +const mockOpts = { + debug: ['1', 'true', 'TRUE'].includes(process.env.DEBUG_MOCKS), +} + +MockDocstoreApi.initialize(23016, mockOpts) +MockDocUpdaterApi.initialize(23003, mockOpts) +MockFilestoreApi.initialize(23009, mockOpts) +MockNotificationsApi.initialize(23042, mockOpts) +MockProjectHistoryApi.initialize(23054, mockOpts) +MockSpellingApi.initialize(23005, mockOpts) +MockV1Api.initialize(25000, mockOpts) +MockV1HistoryApi.initialize(23100, mockOpts) diff --git a/services/web/modules/launchpad/test/acceptance/src/Init.js b/services/web/modules/launchpad/test/acceptance/src/Init.js deleted file mode 100644 index 3757f183ac..0000000000 --- a/services/web/modules/launchpad/test/acceptance/src/Init.js +++ /dev/null @@ -1 +0,0 @@ -require('../../../../../test/acceptance/src/helpers/InitApp') diff --git a/services/web/modules/launchpad/test/acceptance/src/Init.mjs b/services/web/modules/launchpad/test/acceptance/src/Init.mjs new file mode 100644 index 0000000000..8fe4a5f145 --- /dev/null +++ b/services/web/modules/launchpad/test/acceptance/src/Init.mjs @@ -0,0 +1 @@ +import '../../../../../test/acceptance/src/helpers/InitApp.mjs' diff --git a/services/web/modules/server-ce-scripts/test/acceptance/src/Init.js b/services/web/modules/server-ce-scripts/test/acceptance/src/Init.js deleted file mode 100644 index 2bb408cbb7..0000000000 --- a/services/web/modules/server-ce-scripts/test/acceptance/src/Init.js +++ /dev/null @@ -1,14 +0,0 @@ -require('../../../../../test/acceptance/src/helpers/InitApp') -const MockProjectHistoryApi = require('../../../../../test/acceptance/src/mocks/MockProjectHistoryApi') -const MockDocstoreApi = require('../../../../../test/acceptance/src/mocks/MockDocstoreApi') -const MockDocUpdaterApi = require('../../../../../test/acceptance/src/mocks/MockDocUpdaterApi') -const MockV1Api = require('../../../../admin-panel/test/acceptance/src/mocks/MockV1Api') - -const mockOpts = { - debug: ['1', 'true', 'TRUE'].includes(process.env.DEBUG_MOCKS), -} - -MockDocstoreApi.initialize(23016, mockOpts) -MockDocUpdaterApi.initialize(23003, mockOpts) -MockProjectHistoryApi.initialize(23054, mockOpts) -MockV1Api.initialize(25000, mockOpts) diff --git a/services/web/modules/server-ce-scripts/test/acceptance/src/Init.mjs b/services/web/modules/server-ce-scripts/test/acceptance/src/Init.mjs new file mode 100644 index 0000000000..b8513314ec --- /dev/null +++ b/services/web/modules/server-ce-scripts/test/acceptance/src/Init.mjs @@ -0,0 +1,14 @@ +import '../../../../../test/acceptance/src/helpers/InitApp.mjs' +import MockProjectHistoryApi from '../../../../../test/acceptance/src/mocks/MockProjectHistoryApi.js' +import MockDocstoreApi from '../../../../../test/acceptance/src/mocks/MockDocstoreApi.js' +import MockDocUpdaterApi from '../../../../../test/acceptance/src/mocks/MockDocUpdaterApi.js' +import MockV1Api from '../../../../admin-panel/test/acceptance/src/mocks/MockV1Api.js' + +const mockOpts = { + debug: ['1', 'true', 'TRUE'].includes(process.env.DEBUG_MOCKS), +} + +MockDocstoreApi.initialize(23016, mockOpts) +MockDocUpdaterApi.initialize(23003, mockOpts) +MockProjectHistoryApi.initialize(23054, mockOpts) +MockV1Api.initialize(25000, mockOpts) diff --git a/services/web/package.json b/services/web/package.json index 3ff7263360..ffccae972e 100644 --- a/services/web/package.json +++ b/services/web/package.json @@ -2,7 +2,7 @@ "name": "@overleaf/web", "description": "The HTTP front end for Overleaf", "private": true, - "main": "app.js", + "main": "app.mjs", "directories": { "public": "./public" }, @@ -15,8 +15,8 @@ "test:unit:app": "npm run test:unit:run_dir -- test/unit/src", "test:frontend": "NODE_ENV=test TZ=GMT mocha --recursive --timeout 5000 --exit --extension js,jsx,mjs,ts,tsx --grep=$MOCHA_GREP --require test/frontend/bootstrap.js --ignore '**/*.spec.{js,jsx,ts,tsx}' --ignore '**/helpers/**/*.{js,jsx,ts,tsx}' test/frontend modules/*/test/frontend", "test:frontend:coverage": "c8 --all --include 'frontend/js' --include 'modules/*/frontend/js' --exclude 'frontend/js/vendor' --reporter=lcov --reporter=text-summary npm run test:frontend", - "start": "node app.js", - "nodemon": "node --watch app.js --watch-locales", + "start": "node app.mjs", + "nodemon": "node --watch app.mjs --watch-locales", "webpack": "webpack serve --config webpack.config.dev.js", "webpack:production": "webpack --config webpack.config.prod.js", "webpack:profile": "webpack --config webpack.config.prod.js --profile --json > stats.json", diff --git a/services/web/test/acceptance/src/Init.js b/services/web/test/acceptance/src/Init.js deleted file mode 100644 index b872881565..0000000000 --- a/services/web/test/acceptance/src/Init.js +++ /dev/null @@ -1,42 +0,0 @@ -require('./helpers/InitApp') -const Features = require('../../../app/src/infrastructure/Features') - -const MockAnalyticsApi = require('./mocks/MockAnalyticsApi') -const MockChatApi = require('./mocks/MockChatApi') -const MockClsiApi = require('./mocks/MockClsiApi') -const MockDocstoreApi = require('./mocks/MockDocstoreApi') -const MockDocUpdaterApi = require('./mocks/MockDocUpdaterApi') -const MockFilestoreApi = require('./mocks/MockFilestoreApi') -const MockGitBridgeApi = require('./mocks/MockGitBridgeApi') -const MockNotificationsApi = require('./mocks/MockNotificationsApi') -const MockProjectHistoryApi = require('./mocks/MockProjectHistoryApi') -const MockSpellingApi = require('./mocks/MockSpellingApi') -const MockV1Api = require('./mocks/MockV1Api') -const MockV1HistoryApi = require('./mocks/MockV1HistoryApi') -const MockHaveIBeenPwnedApi = require('./mocks/MockHaveIBeenPwnedApi') -const MockThirdPartyDataStoreApi = require('./mocks/MockThirdPartyDataStoreApi') - -const mockOpts = { - debug: ['1', 'true', 'TRUE'].includes(process.env.DEBUG_MOCKS), -} - -MockChatApi.initialize(23010, mockOpts) -MockClsiApi.initialize(23013, mockOpts) -MockDocstoreApi.initialize(23016, mockOpts) -MockDocUpdaterApi.initialize(23003, mockOpts) -MockFilestoreApi.initialize(23009, mockOpts) -MockNotificationsApi.initialize(23042, mockOpts) -MockSpellingApi.initialize(23005, mockOpts) -MockHaveIBeenPwnedApi.initialize(1337, mockOpts) -MockProjectHistoryApi.initialize(23054, mockOpts) -MockV1HistoryApi.initialize(23100, mockOpts) - -if (Features.hasFeature('saas')) { - MockAnalyticsApi.initialize(23050, mockOpts) - MockV1Api.initialize(25000, mockOpts) - MockThirdPartyDataStoreApi.initialize(23002, mockOpts) -} - -if (Features.hasFeature('git-bridge')) { - MockGitBridgeApi.initialize(28000, mockOpts) -} diff --git a/services/web/test/acceptance/src/Init.mjs b/services/web/test/acceptance/src/Init.mjs new file mode 100644 index 0000000000..6681ed6d2f --- /dev/null +++ b/services/web/test/acceptance/src/Init.mjs @@ -0,0 +1,42 @@ +import './helpers/InitApp.mjs' +import Features from '../../../app/src/infrastructure/Features.js' + +import MockAnalyticsApi from './mocks/MockAnalyticsApi.js' +import MockChatApi from './mocks/MockChatApi.js' +import MockClsiApi from './mocks/MockClsiApi.js' +import MockDocstoreApi from './mocks/MockDocstoreApi.js' +import MockDocUpdaterApi from './mocks/MockDocUpdaterApi.js' +import MockFilestoreApi from './mocks/MockFilestoreApi.js' +import MockGitBridgeApi from './mocks/MockGitBridgeApi.js' +import MockNotificationsApi from './mocks/MockNotificationsApi.js' +import MockProjectHistoryApi from './mocks/MockProjectHistoryApi.js' +import MockSpellingApi from './mocks/MockSpellingApi.js' +import MockV1Api from './mocks/MockV1Api.js' +import MockV1HistoryApi from './mocks/MockV1HistoryApi.js' +import MockHaveIBeenPwnedApi from './mocks/MockHaveIBeenPwnedApi.js' +import MockThirdPartyDataStoreApi from './mocks/MockThirdPartyDataStoreApi.js' + +const mockOpts = { + debug: ['1', 'true', 'TRUE'].includes(process.env.DEBUG_MOCKS), +} + +MockChatApi.initialize(23010, mockOpts) +MockClsiApi.initialize(23013, mockOpts) +MockDocstoreApi.initialize(23016, mockOpts) +MockDocUpdaterApi.initialize(23003, mockOpts) +MockFilestoreApi.initialize(23009, mockOpts) +MockNotificationsApi.initialize(23042, mockOpts) +MockSpellingApi.initialize(23005, mockOpts) +MockHaveIBeenPwnedApi.initialize(1337, mockOpts) +MockProjectHistoryApi.initialize(23054, mockOpts) +MockV1HistoryApi.initialize(23100, mockOpts) + +if (Features.hasFeature('saas')) { + MockAnalyticsApi.initialize(23050, mockOpts) + MockV1Api.initialize(25000, mockOpts) + MockThirdPartyDataStoreApi.initialize(23002, mockOpts) +} + +if (Features.hasFeature('git-bridge')) { + MockGitBridgeApi.initialize(28000, mockOpts) +} diff --git a/services/web/test/acceptance/src/helpers/InitApp.js b/services/web/test/acceptance/src/helpers/InitApp.mjs similarity index 76% rename from services/web/test/acceptance/src/helpers/InitApp.js rename to services/web/test/acceptance/src/helpers/InitApp.mjs index 1f5314d525..afa4edf5bc 100644 --- a/services/web/test/acceptance/src/helpers/InitApp.js +++ b/services/web/test/acceptance/src/helpers/InitApp.mjs @@ -1,18 +1,18 @@ -const App = require('../../../../app') -const QueueWorkers = require('../../../../app/src/infrastructure/QueueWorkers') -const MongoHelper = require('./MongoHelper') -const RedisHelper = require('./RedisHelper') -const logger = require('@overleaf/logger') -const Settings = require('@overleaf/settings') -const MockReCAPTCHAApi = require('../mocks/MockReCaptchaApi') -const { - gracefulShutdown, -} = require('../../../../app/src/infrastructure/GracefulShutdown') -const { app } = require('../../../../app/src/infrastructure/Server') -const { injectRouteAfter } = require('./injectRoute') -const SplitTestHandler = require('../../../../app/src/Features/SplitTests/SplitTestHandler') -const SplitTestSessionHandler = require('../../../../app/src/Features/SplitTests/SplitTestSessionHandler') -const Modules = require('../../../../app/src/infrastructure/Modules') +import App from '../../../../app.mjs' +import QueueWorkers from '../../../../app/src/infrastructure/QueueWorkers.js' +import MongoHelper from './MongoHelper.js' +import RedisHelper from './RedisHelper.js' +import logger from '@overleaf/logger' +import Settings from '@overleaf/settings' +import MockReCAPTCHAApi from '../mocks/MockReCaptchaApi.js' +import { gracefulShutdown } from '../../../../app/src/infrastructure/GracefulShutdown.js' +import Server from '../../../../app/src/infrastructure/Server.mjs' +import { injectRouteAfter } from './injectRoute.js' +import SplitTestHandler from '../../../../app/src/Features/SplitTests/SplitTestHandler.js' +import SplitTestSessionHandler from '../../../../app/src/Features/SplitTests/SplitTestSessionHandler.js' +import Modules from '../../../../app/src/infrastructure/Modules.js' + +const app = Server.app logger.logger.level('error')