Quellcode durchsuchen

Convert to ESM

GitOrigin-RevId: 572dafeaddea99be28ec1e1116e49aaf203be340
Andrew Rumble vor 10 Monaten
Ursprung
Commit
7bda755d0e
30 geänderte Dateien mit 448 neuen und 442 gelöschten Zeilen
  1. 36 32
      services/web/app/src/Features/Authentication/AuthenticationController.mjs
  2. 18 18
      services/web/app/src/Features/Authorization/AuthorizationManager.mjs
  3. 18 13
      services/web/app/src/Features/Collaborators/CollaboratorsGetter.mjs
  4. 13 13
      services/web/app/src/Features/Collaborators/CollaboratorsHandler.mjs
  5. 11 11
      services/web/app/src/Features/Compile/ClsiCacheManager.mjs
  6. 10 10
      services/web/app/src/Features/DocumentUpdater/DocumentUpdaterHandler.mjs
  7. 12 12
      services/web/app/src/Features/Editor/EditorController.mjs
  8. 13 12
      services/web/app/src/Features/FileStore/FileStoreHandler.mjs
  9. 6 6
      services/web/app/src/Features/Helpers/AdminAuthorizationHelper.mjs
  10. 13 13
      services/web/app/src/Features/History/HistoryManager.mjs
  11. 23 21
      services/web/app/src/Features/Project/ProjectCreationHandler.mjs
  12. 25 22
      services/web/app/src/Features/Project/ProjectDeleter.mjs
  13. 13 13
      services/web/app/src/Features/Project/ProjectDetailsHandler.mjs
  14. 8 8
      services/web/app/src/Features/Project/ProjectEntityHandler.mjs
  15. 21 19
      services/web/app/src/Features/Project/ProjectEntityMongoUpdateHandler.mjs
  16. 26 29
      services/web/app/src/Features/Project/ProjectEntityUpdateHandler.mjs
  17. 10 10
      services/web/app/src/Features/Project/ProjectGetter.mjs
  18. 9 9
      services/web/app/src/Features/Project/ProjectLocator.mjs
  19. 16 19
      services/web/app/src/Features/Project/ProjectRootDocManager.mjs
  20. 11 13
      services/web/app/src/Features/Subscription/LimitationsManager.mjs
  21. 15 14
      services/web/app/src/Features/Subscription/SubscriptionHandler.mjs
  22. 20 26
      services/web/app/src/Features/Subscription/TeamInvitesHandler.mjs
  23. 19 18
      services/web/app/src/Features/Templates/TemplatesManager.mjs
  24. 9 9
      services/web/app/src/Features/ThirdPartyDataStore/TpdsProjectFlusher.mjs
  25. 16 13
      services/web/app/src/Features/ThirdPartyDataStore/TpdsUpdateSender.mjs
  26. 9 9
      services/web/app/src/Features/Uploads/FileSystemImportManager.mjs
  27. 19 19
      services/web/app/src/Features/Uploads/ProjectUploadManager.mjs
  28. 21 21
      services/web/app/src/Features/User/UserDeleter.mjs
  29. 4 7
      services/web/app/src/Features/User/UserHandler.mjs
  30. 4 3
      services/web/app/src/Features/UserMembership/UserMembershipMiddleware.mjs

+ 36 - 32
services/web/app/src/Features/Authentication/AuthenticationController.mjs

@@ -1,32 +1,32 @@
-const AuthenticationManager = require('./AuthenticationManager')
-const SessionManager = require('./SessionManager')
-const OError = require('@overleaf/o-error')
-const LoginRateLimiter = require('../Security/LoginRateLimiter')
-const UserUpdater = require('../User/UserUpdater')
-const Metrics = require('@overleaf/metrics')
-const logger = require('@overleaf/logger')
-const querystring = require('querystring')
-const Settings = require('@overleaf/settings')
-const basicAuth = require('basic-auth')
-const tsscmp = require('tsscmp')
-const UserHandler = require('../User/UserHandler')
-const UserSessionsManager = require('../User/UserSessionsManager')
-const Analytics = require('../Analytics/AnalyticsManager')
-const passport = require('passport')
-const NotificationsBuilder = require('../Notifications/NotificationsBuilder')
-const UrlHelper = require('../Helpers/UrlHelper')
-const AsyncFormHelper = require('../Helpers/AsyncFormHelper')
-const _ = require('lodash')
-const UserAuditLogHandler = require('../User/UserAuditLogHandler')
-const AnalyticsRegistrationSourceHelper = require('../Analytics/AnalyticsRegistrationSourceHelper')
-const {
-  acceptsJson,
-} = require('../../infrastructure/RequestContentTypeDetection')
-const { hasAdminAccess } = require('../Helpers/AdminAuthorizationHelper')
-const Modules = require('../../infrastructure/Modules')
-const { expressify, promisify } = require('@overleaf/promise-utils')
-const { handleAuthenticateErrors } = require('./AuthenticationErrors')
-const EmailHelper = require('../Helpers/EmailHelper')
+import AuthenticationManager from './AuthenticationManager.js'
+import SessionManager from './SessionManager.js'
+import OError from '@overleaf/o-error'
+import LoginRateLimiter from '../Security/LoginRateLimiter.js'
+import UserUpdater from '../User/UserUpdater.js'
+import Metrics from '@overleaf/metrics'
+import logger from '@overleaf/logger'
+import querystring from 'node:querystring'
+import Settings from '@overleaf/settings'
+import basicAuth from 'basic-auth'
+import tsscmp from 'tsscmp'
+import UserHandler from '../User/UserHandler.mjs'
+import UserSessionsManager from '../User/UserSessionsManager.js'
+import Analytics from '../Analytics/AnalyticsManager.js'
+import passport from 'passport'
+import NotificationsBuilder from '../Notifications/NotificationsBuilder.js'
+import UrlHelper from '../Helpers/UrlHelper.js'
+import AsyncFormHelper from '../Helpers/AsyncFormHelper.js'
+import _ from 'lodash'
+import UserAuditLogHandler from '../User/UserAuditLogHandler.js'
+import AnalyticsRegistrationSourceHelper from '../Analytics/AnalyticsRegistrationSourceHelper.js'
+import { acceptsJson } from '../../infrastructure/RequestContentTypeDetection.js'
+import AdminAuthorizationHelper from '../Helpers/AdminAuthorizationHelper.mjs'
+import Modules from '../../infrastructure/Modules.js'
+import { expressify, promisify } from '@overleaf/promise-utils'
+import { handleAuthenticateErrors } from './AuthenticationErrors.js'
+import EmailHelper from '../Helpers/EmailHelper.js'
+
+const { hasAdminAccess } = AdminAuthorizationHelper
 
 function send401WithChallenge(res) {
   res.setHeader('WWW-Authenticate', 'OverleafLogin')
@@ -391,9 +391,13 @@ const AuthenticationController = {
       )
     }
 
-    // require this here because module may not be included in some versions
-    const Oauth2Server = require('../../../../modules/oauth2-server/app/src/Oauth2Server')
     const middleware = async (req, res, next) => {
+      const Oauth2Server = (
+        await import(
+          '../../../../modules/oauth2-server/app/src/Oauth2Server.js'
+        )
+      ).default
+
       const request = new Oauth2Server.Request(req)
       const response = new Oauth2Server.Response(res)
       try {
@@ -681,4 +685,4 @@ AuthenticationController.promises = {
   finishLogin: AuthenticationController._finishLoginAsync,
 }
 
-module.exports = AuthenticationController
+export default AuthenticationController

+ 18 - 18
services/web/app/src/Features/Authorization/AuthorizationManager.mjs

@@ -1,20 +1,20 @@
-const { callbackify } = require('util')
-const { ObjectId } = require('mongodb-legacy')
-const Features = require('../../infrastructure/Features')
-const CollaboratorsGetter = require('../Collaborators/CollaboratorsGetter')
-const CollaboratorsHandler = require('../Collaborators/CollaboratorsHandler')
-const ProjectGetter = require('../Project/ProjectGetter')
-const { User } = require('../../models/User')
-const PrivilegeLevels = require('./PrivilegeLevels')
-const TokenAccessHandler = require('../TokenAccess/TokenAccessHandler')
-const PublicAccessLevels = require('./PublicAccessLevels')
-const Errors = require('../Errors/Errors')
-const {
-  hasAdminAccess,
-  getAdminCapabilities,
-} = require('../Helpers/AdminAuthorizationHelper')
-const Settings = require('@overleaf/settings')
-const ChatApiHandler = require('../Chat/ChatApiHandler')
+import { callbackify } from 'node:util'
+import mongodb from 'mongodb-legacy'
+import Features from '../../infrastructure/Features.js'
+import CollaboratorsGetter from '../Collaborators/CollaboratorsGetter.mjs'
+import CollaboratorsHandler from '../Collaborators/CollaboratorsHandler.mjs'
+import ProjectGetter from '../Project/ProjectGetter.mjs'
+import { User } from '../../models/User.js'
+import PrivilegeLevels from './PrivilegeLevels.js'
+import TokenAccessHandler from '../TokenAccess/TokenAccessHandler.js'
+import PublicAccessLevels from './PublicAccessLevels.js'
+import Errors from '../Errors/Errors.js'
+import AdminAuthorizationHelper from '../Helpers/AdminAuthorizationHelper.mjs'
+import Settings from '@overleaf/settings'
+import ChatApiHandler from '../Chat/ChatApiHandler.js'
+
+const { hasAdminAccess, getAdminCapabilities } = AdminAuthorizationHelper
+const { ObjectId } = mongodb
 
 function isRestrictedUser(
   userId,
@@ -401,7 +401,7 @@ async function canUserDeleteOrResolveThread(
   }
 }
 
-module.exports = {
+export default {
   canUserReadProject: callbackify(canUserReadProject),
   canUserWriteProjectContent: callbackify(canUserWriteProjectContent),
   canUserWriteOrReviewProjectContent: callbackify(

+ 18 - 13
services/web/app/src/Features/Collaborators/CollaboratorsGetter.mjs

@@ -1,16 +1,21 @@
 // @ts-check
-const { callbackify } = require('util')
-const pLimit = require('p-limit')
-const { ObjectId } = require('mongodb-legacy')
-const OError = require('@overleaf/o-error')
-const { Project } = require('../../models/Project')
-const UserGetter = require('../User/UserGetter')
-const ProjectGetter = require('../Project/ProjectGetter')
-const PublicAccessLevels = require('../Authorization/PublicAccessLevels')
-const Errors = require('../Errors/Errors')
-const ProjectEditorHandler = require('../Project/ProjectEditorHandler')
-const Sources = require('../Authorization/Sources')
-const PrivilegeLevels = require('../Authorization/PrivilegeLevels')
+import { callbackify } from 'node:util'
+
+import pLimit from 'p-limit'
+import mongodb from 'mongodb-legacy'
+import OError from '@overleaf/o-error'
+import { Project } from '../../models/Project.js'
+import UserGetter from '../User/UserGetter.js'
+import ProjectGetter from '../Project/ProjectGetter.mjs'
+import PublicAccessLevels from '../Authorization/PublicAccessLevels.js'
+import Errors from '../Errors/Errors.js'
+import ProjectEditorHandler from '../Project/ProjectEditorHandler.js'
+import Sources from '../Authorization/Sources.js'
+import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'
+
+const { ObjectId } = mongodb
+
+/** @import {ObjectId} from "mongodb-legacy" */
 
 /** @import { PrivilegeLevel, Source, PublicAccessLevel } from "../Authorization/types" */
 
@@ -542,7 +547,7 @@ async function _loadMembers(members) {
     .filter(r => r != null)
 }
 
-module.exports = {
+export default {
   getMemberIdsWithPrivilegeLevels: callbackify(getMemberIdsWithPrivilegeLevels),
   getMemberIds: callbackify(getMemberIds),
   getInvitedMemberIds: callbackify(getInvitedMemberIds),

+ 13 - 13
services/web/app/src/Features/Collaborators/CollaboratorsHandler.mjs

@@ -1,17 +1,17 @@
-const { callbackify } = require('util')
-const OError = require('@overleaf/o-error')
-const { Project } = require('../../models/Project')
-const ProjectGetter = require('../Project/ProjectGetter')
-const logger = require('@overleaf/logger')
-const ContactManager = require('../Contacts/ContactManager')
-const PrivilegeLevels = require('../Authorization/PrivilegeLevels')
-const TpdsProjectFlusher = require('../ThirdPartyDataStore/TpdsProjectFlusher')
-const CollaboratorsGetter = require('./CollaboratorsGetter')
-const Errors = require('../Errors/Errors')
-const TpdsUpdateSender = require('../ThirdPartyDataStore/TpdsUpdateSender')
-const EditorRealTimeController = require('../Editor/EditorRealTimeController')
+import { callbackify } from 'node:util'
+import OError from '@overleaf/o-error'
+import { Project } from '../../models/Project.js'
+import ProjectGetter from '../Project/ProjectGetter.mjs'
+import logger from '@overleaf/logger'
+import ContactManager from '../Contacts/ContactManager.js'
+import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'
+import TpdsProjectFlusher from '../ThirdPartyDataStore/TpdsProjectFlusher.mjs'
+import CollaboratorsGetter from './CollaboratorsGetter.mjs'
+import Errors from '../Errors/Errors.js'
+import TpdsUpdateSender from '../ThirdPartyDataStore/TpdsUpdateSender.mjs'
+import EditorRealTimeController from '../Editor/EditorRealTimeController.js'
 
-module.exports = {
+export default {
   userIsTokenMember: callbackify(userIsTokenMember),
   removeUserFromProject: callbackify(removeUserFromProject),
   removeUserFromAllProjects: callbackify(removeUserFromAllProjects),

+ 11 - 11
services/web/app/src/Features/Compile/ClsiCacheManager.mjs

@@ -1,13 +1,13 @@
-const _ = require('lodash')
-const { NotFoundError, ResourceGoneError } = require('../Errors/Errors')
-const ClsiCacheHandler = require('./ClsiCacheHandler')
-const DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler')
-const ProjectGetter = require('../Project/ProjectGetter')
-const SplitTestHandler = require('../SplitTests/SplitTestHandler')
-const UserGetter = require('../User/UserGetter')
-const Settings = require('@overleaf/settings')
-const { fetchJson, RequestFailedError } = require('@overleaf/fetch-utils')
-const Metrics = require('@overleaf/metrics')
+import _ from 'lodash'
+import { NotFoundError, ResourceGoneError } from '../Errors/Errors.js'
+import ClsiCacheHandler from './ClsiCacheHandler.js'
+import DocumentUpdaterHandler from '../DocumentUpdater/DocumentUpdaterHandler.mjs'
+import ProjectGetter from '../Project/ProjectGetter.mjs'
+import SplitTestHandler from '../SplitTests/SplitTestHandler.js'
+import UserGetter from '../User/UserGetter.js'
+import Settings from '@overleaf/settings'
+import { fetchJson, RequestFailedError } from '@overleaf/fetch-utils'
+import Metrics from '@overleaf/metrics'
 
 /**
  * Get the most recent build and metadata
@@ -228,7 +228,7 @@ async function prepareClsiCache(
   }
 }
 
-module.exports = {
+export default {
   getLatestBuildFromCache,
   getLatestCompileResult,
   prepareClsiCache,

+ 10 - 10
services/web/app/src/Features/DocumentUpdater/DocumentUpdaterHandler.mjs

@@ -1,16 +1,16 @@
-const OError = require('@overleaf/o-error')
-const settings = require('@overleaf/settings')
-const {
+import OError from '@overleaf/o-error'
+import settings from '@overleaf/settings'
+import {
   fetchJson,
   fetchNothing,
   fetchString,
   RequestFailedError,
-} = require('@overleaf/fetch-utils')
-const _ = require('lodash')
-const logger = require('@overleaf/logger')
-const { callbackifyAll } = require('@overleaf/promise-utils')
-const ProjectGetter = require('../Project/ProjectGetter')
-const Modules = require('../../infrastructure/Modules')
+} from '@overleaf/fetch-utils'
+import _ from 'lodash'
+import logger from '@overleaf/logger'
+import { callbackifyAll } from '@overleaf/promise-utils'
+import ProjectGetter from '../Project/ProjectGetter.mjs'
+import Modules from '../../infrastructure/Modules.js'
 
 const REQUEST_TIMEOUT_MS = 30 * 1000
 const RESYNC_TIMEOUT_MS = 6 * 60 * 1000
@@ -543,7 +543,7 @@ const DocumentUpdaterHandler = {
   getDocumentWithHistoryRanges,
 }
 
-module.exports = {
+export default {
   ...callbackifyAll(DocumentUpdaterHandler, {
     multiResult: {
       getDocument: ['lines', 'version', 'ranges', 'ops'],

+ 12 - 12
services/web/app/src/Features/Editor/EditorController.mjs

@@ -1,14 +1,14 @@
-const logger = require('@overleaf/logger')
-const OError = require('@overleaf/o-error')
-const Metrics = require('@overleaf/metrics')
-const ProjectEntityUpdateHandler = require('../Project/ProjectEntityUpdateHandler')
-const ProjectOptionsHandler = require('../Project/ProjectOptionsHandler')
-const ProjectDetailsHandler = require('../Project/ProjectDetailsHandler')
-const ProjectDeleter = require('../Project/ProjectDeleter')
-const EditorRealTimeController = require('./EditorRealTimeController')
-const async = require('async')
-const PublicAccessLevels = require('../Authorization/PublicAccessLevels')
-const { promisifyAll } = require('@overleaf/promise-utils')
+import logger from '@overleaf/logger'
+import OError from '@overleaf/o-error'
+import Metrics from '@overleaf/metrics'
+import ProjectEntityUpdateHandler from '../Project/ProjectEntityUpdateHandler.mjs'
+import ProjectOptionsHandler from '../Project/ProjectOptionsHandler.js'
+import ProjectDetailsHandler from '../Project/ProjectDetailsHandler.mjs'
+import ProjectDeleter from '../Project/ProjectDeleter.mjs'
+import EditorRealTimeController from './EditorRealTimeController.js'
+import async from 'async'
+import PublicAccessLevels from '../Authorization/PublicAccessLevels.js'
+import { promisifyAll } from '@overleaf/promise-utils'
 
 const EditorController = {
   addDoc(projectId, folderId, docName, docLines, source, userId, callback) {
@@ -692,4 +692,4 @@ EditorController.promises = promisifyAll(EditorController, {
     mkdirp: ['newFolders', 'lastFolder'],
   },
 })
-module.exports = EditorController
+export default EditorController

+ 13 - 12
services/web/app/src/Features/FileStore/FileStoreHandler.mjs

@@ -1,13 +1,13 @@
-const logger = require('@overleaf/logger')
-const fs = require('fs')
-const Async = require('async')
-const FileHashManager = require('./FileHashManager')
-const HistoryManager = require('../History/HistoryManager')
-const ProjectDetailsHandler = require('../Project/ProjectDetailsHandler')
-const { File } = require('../../models/File')
-const OError = require('@overleaf/o-error')
-const { promisifyAll } = require('@overleaf/promise-utils')
-const Modules = require('../../infrastructure/Modules')
+import logger from '@overleaf/logger'
+import fs from 'node:fs'
+import Async from 'async'
+import FileHashManager from './FileHashManager.js'
+import HistoryManager from '../History/HistoryManager.mjs'
+import ProjectDetailsHandler from '../Project/ProjectDetailsHandler.mjs'
+import { File } from '../../models/File.js'
+import OError from '@overleaf/o-error'
+import { promisifyAll } from '@overleaf/promise-utils'
+import Modules from '../../infrastructure/Modules.js'
 
 const FileStoreHandler = {
   RETRY_ATTEMPTS: 3,
@@ -115,10 +115,11 @@ const FileStoreHandler = {
   },
 }
 
-module.exports = FileStoreHandler
-module.exports.promises = promisifyAll(FileStoreHandler, {
+FileStoreHandler.promises = promisifyAll(FileStoreHandler, {
   multiResult: {
     uploadFileFromDisk: ['fileRef', 'createdBlob', 'size'],
     uploadFileFromDiskWithHistoryId: ['fileRef', 'createdBlob', 'size'],
   },
 })
+
+export default FileStoreHandler

+ 6 - 6
services/web/app/src/Features/Helpers/AdminAuthorizationHelper.mjs

@@ -1,10 +1,10 @@
-const Settings = require('@overleaf/settings')
-const Modules = require('../../infrastructure/Modules')
-const { expressify } = require('@overleaf/promise-utils')
-const SessionManager = require('../Authentication/SessionManager')
-const logger = require('@overleaf/logger')
+import Settings from '@overleaf/settings'
+import Modules from '../../infrastructure/Modules.js'
+import { expressify } from '@overleaf/promise-utils'
+import SessionManager from '../Authentication/SessionManager.js'
+import logger from '@overleaf/logger'
 
-module.exports = {
+export default {
   hasAdminAccess,
   hasAdminCapability,
   canRedirectToAdminDomain,

+ 13 - 13
services/web/app/src/Features/History/HistoryManager.mjs

@@ -1,19 +1,19 @@
-const { callbackify } = require('util')
-const {
+import { callbackify } from 'node:util'
+import {
   fetchJson,
   fetchNothing,
   fetchStreamWithResponse,
   RequestFailedError,
-} = require('@overleaf/fetch-utils')
-const fs = require('fs')
-const settings = require('@overleaf/settings')
-const OError = require('@overleaf/o-error')
-const UserGetter = require('../User/UserGetter')
-const ProjectGetter = require('../Project/ProjectGetter')
-const HistoryBackupDeletionHandler = require('./HistoryBackupDeletionHandler')
-const { db, waitForDb } = require('../../infrastructure/mongodb')
-const Metrics = require('@overleaf/metrics')
-const { NotFoundError } = require('../Errors/Errors')
+} from '@overleaf/fetch-utils'
+import fs from 'node:fs'
+import settings from '@overleaf/settings'
+import OError from '@overleaf/o-error'
+import UserGetter from '../User/UserGetter.js'
+import ProjectGetter from '../Project/ProjectGetter.mjs'
+import HistoryBackupDeletionHandler from './HistoryBackupDeletionHandler.js'
+import { db, waitForDb } from '../../infrastructure/mongodb.js'
+import Metrics from '@overleaf/metrics'
+import { NotFoundError } from '../Errors/Errors.js'
 
 const HISTORY_V1_URL = settings.apis.v1_history.url
 const HISTORY_V1_BASIC_AUTH = {
@@ -404,7 +404,7 @@ function _userView(user) {
 
 const loadGlobalBlobsPromise = loadGlobalBlobs()
 
-module.exports = {
+export default {
   getFilestoreBlobURL,
   loadGlobalBlobsPromise,
   initializeProject: callbackify(initializeProject),

+ 23 - 21
services/web/app/src/Features/Project/ProjectCreationHandler.mjs

@@ -1,21 +1,23 @@
-const OError = require('@overleaf/o-error')
-const metrics = require('@overleaf/metrics')
-const Settings = require('@overleaf/settings')
-const { ObjectId } = require('mongodb-legacy')
-const Features = require('../../infrastructure/Features')
-const { Project } = require('../../models/Project')
-const { Folder } = require('../../models/Folder')
-const ProjectEntityUpdateHandler = require('./ProjectEntityUpdateHandler')
-const ProjectDetailsHandler = require('./ProjectDetailsHandler')
-const HistoryManager = require('../History/HistoryManager')
-const { User } = require('../../models/User')
-const fs = require('fs')
-const path = require('path')
-const { callbackify } = require('util')
-const _ = require('lodash')
-const AnalyticsManager = require('../Analytics/AnalyticsManager')
-const TpdsUpdateSender = require('../ThirdPartyDataStore/TpdsUpdateSender')
-const SplitTestHandler = require('../SplitTests/SplitTestHandler')
+import OError from '@overleaf/o-error'
+import metrics from '@overleaf/metrics'
+import Settings from '@overleaf/settings'
+import mongodb from 'mongodb-legacy'
+import Features from '../../infrastructure/Features.js'
+import { Project } from '../../models/Project.js'
+import { Folder } from '../../models/Folder.js'
+import ProjectEntityUpdateHandler from './ProjectEntityUpdateHandler.mjs'
+import ProjectDetailsHandler from './ProjectDetailsHandler.mjs'
+import HistoryManager from '../History/HistoryManager.mjs'
+import { User } from '../../models/User.js'
+import fs from 'node:fs'
+import path from 'node:path'
+import { callbackify } from 'node:util'
+import _ from 'lodash'
+import AnalyticsManager from '../Analytics/AnalyticsManager.js'
+import TpdsUpdateSender from '../ThirdPartyDataStore/TpdsUpdateSender.mjs'
+import SplitTestHandler from '../SplitTests/SplitTestHandler.js'
+
+const { ObjectId } = mongodb
 
 const MONTH_NAMES = [
   'January',
@@ -128,7 +130,7 @@ async function _addExampleProjectFiles(ownerId, projectName, project) {
   )
 
   const frogPath = path.join(
-    __dirname,
+    import.meta.dirname,
     `/../../../templates/project_files/${templateProjectDir}/frog.jpg`
   )
   await ProjectEntityUpdateHandler.promises.addFile(
@@ -227,7 +229,7 @@ async function _buildTemplate(templateName, userId, projectName) {
   const user = await User.findById(userId, 'first_name last_name')
 
   const templatePath = path.join(
-    __dirname,
+    import.meta.dirname,
     `/../../../templates/project_files/${templateName}`
   )
   const template = fs.readFileSync(templatePath)
@@ -241,7 +243,7 @@ async function _buildTemplate(templateName, userId, projectName) {
   return output.split('\n')
 }
 
-module.exports = {
+export default {
   createBlankProject: callbackify(createBlankProject),
   createProjectFromSnippet: callbackify(createProjectFromSnippet),
   createBasicProject: callbackify(createBasicProject),

+ 25 - 22
services/web/app/src/Features/Project/ProjectDeleter.mjs

@@ -1,28 +1,31 @@
-const _ = require('lodash')
-const { db, ObjectId } = require('../../infrastructure/mongodb')
-const Modules = require('../../infrastructure/Modules')
-const { callbackify } = require('util')
-const { Project } = require('../../models/Project')
-const { DeletedProject } = require('../../models/DeletedProject')
-const { ProjectAuditLogEntry } = require('../../models/ProjectAuditLogEntry')
-const Errors = require('../Errors/Errors')
-const logger = require('@overleaf/logger')
-const Settings = require('@overleaf/settings')
-const DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler')
-const TagsHandler = require('../Tags/TagsHandler')
-const ProjectDetailsHandler = require('./ProjectDetailsHandler')
-const CollaboratorsHandler = require('../Collaborators/CollaboratorsHandler')
-const CollaboratorsGetter = require('../Collaborators/CollaboratorsGetter')
-const DocstoreManager = require('../Docstore/DocstoreManager')
-const EditorRealTimeController = require('../Editor/EditorRealTimeController')
-const HistoryManager = require('../History/HistoryManager')
-const ChatApiHandler = require('../Chat/ChatApiHandler')
-const { promiseMapWithLimit } = require('@overleaf/promise-utils')
-const { READ_PREFERENCE_SECONDARY } = require('../../infrastructure/mongodb')
+import _ from 'lodash'
+import {
+  db,
+  ObjectId,
+  READ_PREFERENCE_SECONDARY,
+} from '../../infrastructure/mongodb.js'
+import Modules from '../../infrastructure/Modules.js'
+import { callbackify } from 'node:util'
+import { Project } from '../../models/Project.js'
+import { DeletedProject } from '../../models/DeletedProject.js'
+import { ProjectAuditLogEntry } from '../../models/ProjectAuditLogEntry.js'
+import Errors from '../Errors/Errors.js'
+import logger from '@overleaf/logger'
+import Settings from '@overleaf/settings'
+import DocumentUpdaterHandler from '../DocumentUpdater/DocumentUpdaterHandler.mjs'
+import TagsHandler from '../Tags/TagsHandler.js'
+import ProjectDetailsHandler from './ProjectDetailsHandler.mjs'
+import CollaboratorsHandler from '../Collaborators/CollaboratorsHandler.mjs'
+import CollaboratorsGetter from '../Collaborators/CollaboratorsGetter.mjs'
+import DocstoreManager from '../Docstore/DocstoreManager.js'
+import EditorRealTimeController from '../Editor/EditorRealTimeController.js'
+import HistoryManager from '../History/HistoryManager.mjs'
+import ChatApiHandler from '../Chat/ChatApiHandler.js'
+import { promiseMapWithLimit } from '@overleaf/promise-utils'
 
 const PROJECT_EXPIRATION_BATCH_SIZE = 10000
 
-module.exports = {
+export default {
   markAsDeletedByExternalSource: callbackify(markAsDeletedByExternalSource),
   unmarkAsDeletedByExternalSource: callbackify(unmarkAsDeletedByExternalSource),
   deleteUsersProjects: callbackify(deleteUsersProjects),

+ 13 - 13
services/web/app/src/Features/Project/ProjectDetailsHandler.mjs

@@ -1,19 +1,19 @@
-const _ = require('lodash')
-const ProjectGetter = require('./ProjectGetter')
-const UserGetter = require('../User/UserGetter')
-const { Project } = require('../../models/Project')
-const logger = require('@overleaf/logger')
-const TpdsUpdateSender = require('../ThirdPartyDataStore/TpdsUpdateSender')
-const PublicAccessLevels = require('../Authorization/PublicAccessLevels')
-const Errors = require('../Errors/Errors')
-const TokenGenerator = require('../TokenGenerator/TokenGenerator')
-const ProjectHelper = require('./ProjectHelper')
-const settings = require('@overleaf/settings')
-const { callbackify } = require('util')
+import _ from 'lodash'
+import ProjectGetter from './ProjectGetter.mjs'
+import UserGetter from '../User/UserGetter.js'
+import { Project } from '../../models/Project.js'
+import logger from '@overleaf/logger'
+import TpdsUpdateSender from '../ThirdPartyDataStore/TpdsUpdateSender.mjs'
+import PublicAccessLevels from '../Authorization/PublicAccessLevels.js'
+import Errors from '../Errors/Errors.js'
+import TokenGenerator from '../TokenGenerator/TokenGenerator.js'
+import ProjectHelper from './ProjectHelper.js'
+import settings from '@overleaf/settings'
+import { callbackify } from 'node:util'
 
 const MAX_PROJECT_NAME_LENGTH = 150
 
-module.exports = {
+export default {
   MAX_PROJECT_NAME_LENGTH,
   getDetails: callbackify(getDetails),
   getProjectDescription: callbackify(getProjectDescription),

+ 8 - 8
services/web/app/src/Features/Project/ProjectEntityHandler.mjs

@@ -1,10 +1,10 @@
-const path = require('path')
-const DocstoreManager = require('../Docstore/DocstoreManager')
-const Errors = require('../Errors/Errors')
-const ProjectGetter = require('./ProjectGetter')
-const { callbackifyAll } = require('@overleaf/promise-utils')
-const OError = require('@overleaf/o-error')
-const { iterablePaths } = require('./IterablePath')
+import path from 'node:path'
+import DocstoreManager from '../Docstore/DocstoreManager.js'
+import Errors from '../Errors/Errors.js'
+import ProjectGetter from './ProjectGetter.mjs'
+import { callbackifyAll } from '@overleaf/promise-utils'
+import OError from '@overleaf/o-error'
+import { iterablePaths } from './IterablePath.js'
 
 async function getAllDocs(projectId) {
   // We get the path and name info from the project, and the lines and
@@ -207,7 +207,7 @@ const ProjectEntityHandler = {
   _getAllFolders,
 }
 
-module.exports = {
+export default {
   ...callbackifyAll(ProjectEntityHandler, {
     multiResult: {
       getDoc: ['lines', 'rev', 'version', 'ranges'],

+ 21 - 19
services/web/app/src/Features/Project/ProjectEntityMongoUpdateHandler.mjs

@@ -1,21 +1,23 @@
-const { callbackify } = require('util')
-const { callbackifyMultiResult } = require('@overleaf/promise-utils')
-const logger = require('@overleaf/logger')
-const path = require('path')
-const { ObjectId } = require('mongodb-legacy')
-const Settings = require('@overleaf/settings')
-const OError = require('@overleaf/o-error')
-const CooldownManager = require('../Cooldown/CooldownManager')
-const Errors = require('../Errors/Errors')
-const { Folder } = require('../../models/Folder')
-const LockManager = require('../../infrastructure/LockManager')
-const { Project } = require('../../models/Project')
-const ProjectEntityHandler = require('./ProjectEntityHandler')
-const ProjectGetter = require('./ProjectGetter')
-const ProjectLocator = require('./ProjectLocator')
-const FolderStructureBuilder = require('./FolderStructureBuilder')
-const SafePath = require('./SafePath')
-const { iterablePaths } = require('./IterablePath')
+import { callbackify } from 'node:util'
+import { callbackifyMultiResult } from '@overleaf/promise-utils'
+import logger from '@overleaf/logger'
+import path from 'node:path'
+import mongodb from 'mongodb-legacy'
+import Settings from '@overleaf/settings'
+import OError from '@overleaf/o-error'
+import CooldownManager from '../Cooldown/CooldownManager.js'
+import Errors from '../Errors/Errors.js'
+import { Folder } from '../../models/Folder.js'
+import LockManager from '../../infrastructure/LockManager.js'
+import { Project } from '../../models/Project.js'
+import ProjectEntityHandler from './ProjectEntityHandler.mjs'
+import ProjectGetter from './ProjectGetter.mjs'
+import ProjectLocator from './ProjectLocator.mjs'
+import FolderStructureBuilder from './FolderStructureBuilder.js'
+import SafePath from './SafePath.js'
+import { iterablePaths } from './IterablePath.js'
+
+const { ObjectId } = mongodb
 
 const LOCK_NAMESPACE = 'mongoTransaction'
 const ENTITY_TYPE_TO_MONGO_PATH_SEGMENT = {
@@ -28,7 +30,7 @@ const ENTITY_TYPE_TO_MONGO_PATH_SEGMENT = {
   folders: 'folders',
 }
 
-module.exports = {
+export default {
   LOCK_NAMESPACE,
   addDoc: callbackifyMultiResult(wrapWithLock(addDoc), ['result', 'project']),
   addFile: callbackifyMultiResult(wrapWithLock(addFile), ['result', 'project']),

+ 26 - 29
services/web/app/src/Features/Project/ProjectEntityUpdateHandler.mjs

@@ -1,31 +1,28 @@
-const _ = require('lodash')
-const OError = require('@overleaf/o-error')
-const logger = require('@overleaf/logger')
-const Settings = require('@overleaf/settings')
-const Path = require('path')
-const fs = require('fs')
-const { Doc } = require('../../models/Doc')
-const DocstoreManager = require('../Docstore/DocstoreManager')
-const DocumentUpdaterHandler = require('../../Features/DocumentUpdater/DocumentUpdaterHandler')
-const Errors = require('../Errors/Errors')
-const FileStoreHandler = require('../FileStore/FileStoreHandler')
-const LockManager = require('../../infrastructure/LockManager')
-const { Project } = require('../../models/Project')
-const ProjectEntityHandler = require('./ProjectEntityHandler')
-const ProjectGetter = require('./ProjectGetter')
-const ProjectLocator = require('./ProjectLocator')
-const ProjectOptionsHandler = require('./ProjectOptionsHandler')
-const ProjectUpdateHandler = require('./ProjectUpdateHandler')
-const ProjectEntityMongoUpdateHandler = require('./ProjectEntityMongoUpdateHandler')
-const SafePath = require('./SafePath')
-const TpdsUpdateSender = require('../ThirdPartyDataStore/TpdsUpdateSender')
-const FileWriter = require('../../infrastructure/FileWriter')
-const EditorRealTimeController = require('../Editor/EditorRealTimeController')
-const {
-  callbackifyMultiResult,
-  callbackify,
-} = require('@overleaf/promise-utils')
-const { iterablePaths } = require('./IterablePath')
+import _ from 'lodash'
+import OError from '@overleaf/o-error'
+import logger from '@overleaf/logger'
+import Settings from '@overleaf/settings'
+import Path from 'node:path'
+import fs from 'node:fs'
+import { Doc } from '../../models/Doc.js'
+import DocstoreManager from '../Docstore/DocstoreManager.js'
+import DocumentUpdaterHandler from '../../Features/DocumentUpdater/DocumentUpdaterHandler.mjs'
+import Errors from '../Errors/Errors.js'
+import FileStoreHandler from '../FileStore/FileStoreHandler.mjs'
+import LockManager from '../../infrastructure/LockManager.js'
+import { Project } from '../../models/Project.js'
+import ProjectEntityHandler from './ProjectEntityHandler.mjs'
+import ProjectGetter from './ProjectGetter.mjs'
+import ProjectLocator from './ProjectLocator.mjs'
+import ProjectOptionsHandler from './ProjectOptionsHandler.js'
+import ProjectUpdateHandler from './ProjectUpdateHandler.js'
+import ProjectEntityMongoUpdateHandler from './ProjectEntityMongoUpdateHandler.mjs'
+import SafePath from './SafePath.js'
+import TpdsUpdateSender from '../ThirdPartyDataStore/TpdsUpdateSender.mjs'
+import FileWriter from '../../infrastructure/FileWriter.js'
+import EditorRealTimeController from '../Editor/EditorRealTimeController.js'
+import { callbackifyMultiResult, callbackify } from '@overleaf/promise-utils'
+import { iterablePaths } from './IterablePath.js'
 
 const LOCK_NAMESPACE = 'sequentialProjectStructureUpdateLock'
 const VALID_ROOT_DOC_EXTENSIONS = Settings.validRootDocExtensions
@@ -1697,4 +1694,4 @@ function _listSubtree(entity, entityType, entityPath) {
   }
 }
 
-module.exports = ProjectEntityUpdateHandler
+export default ProjectEntityUpdateHandler

+ 10 - 10
services/web/app/src/Features/Project/ProjectGetter.mjs

@@ -1,10 +1,12 @@
-const { db } = require('../../infrastructure/mongodb')
-const { normalizeQuery } = require('../Helpers/Mongo')
-const OError = require('@overleaf/o-error')
-const { Project } = require('../../models/Project')
-const LockManager = require('../../infrastructure/LockManager')
-const { DeletedProject } = require('../../models/DeletedProject')
-const { callbackifyAll } = require('@overleaf/promise-utils')
+import { db } from '../../infrastructure/mongodb.js'
+import { normalizeQuery } from '../Helpers/Mongo.js'
+import OError from '@overleaf/o-error'
+import { Project } from '../../models/Project.js'
+import LockManager from '../../infrastructure/LockManager.js'
+import { DeletedProject } from '../../models/DeletedProject.js'
+import { callbackifyAll } from '@overleaf/promise-utils'
+import ProjectEntityMongoUpdateHandler from './ProjectEntityMongoUpdateHandler.mjs'
+import CollaboratorsGetter from '../Collaborators/CollaboratorsGetter.mjs'
 
 const ProjectGetter = {
   EXCLUDE_DEPTH: 8,
@@ -35,7 +37,6 @@ const ProjectGetter = {
     }
 
     if (projection.rootFolder || Object.keys(projection).length === 0) {
-      const ProjectEntityMongoUpdateHandler = require('./ProjectEntityMongoUpdateHandler')
       return await LockManager.promises.runWithLock(
         ProjectEntityMongoUpdateHandler.LOCK_NAMESPACE,
         projectId,
@@ -87,7 +88,6 @@ const ProjectGetter = {
    * @return {Promise<any>}
    */
   async findAllUsersProjects(userId, fields) {
-    const CollaboratorsGetter = require('../Collaborators/CollaboratorsGetter')
     const ownedProjects = await Project.find(
       { owner_ref: userId },
       fields
@@ -157,7 +157,7 @@ const ProjectGetter = {
   },
 }
 
-module.exports = {
+export default {
   ...callbackifyAll(ProjectGetter),
   promises: ProjectGetter,
 }

+ 9 - 9
services/web/app/src/Features/Project/ProjectLocator.mjs

@@ -1,11 +1,11 @@
-const _ = require('lodash')
-const logger = require('@overleaf/logger')
-const OError = require('@overleaf/o-error')
-const async = require('async')
-const ProjectGetter = require('./ProjectGetter')
-const Errors = require('../Errors/Errors')
-const { promisifyMultiResult } = require('@overleaf/promise-utils')
-const { iterablePaths } = require('./IterablePath')
+import _ from 'lodash'
+import logger from '@overleaf/logger'
+import OError from '@overleaf/o-error'
+import async from 'async'
+import ProjectGetter from './ProjectGetter.mjs'
+import Errors from '../Errors/Errors.js'
+import { promisifyMultiResult } from '@overleaf/promise-utils'
+import { iterablePaths } from './IterablePath.js'
 
 /**
  * @param project
@@ -328,7 +328,7 @@ function findElementByMongoPath(project, mongoPath) {
   return node
 }
 
-module.exports = {
+export default {
   findElement,
   findElementByPath,
   findRootDoc,

+ 16 - 19
services/web/app/src/Features/Project/ProjectRootDocManager.mjs

@@ -12,25 +12,21 @@
  * DS207: Consider shorter variations of null checks
  * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  */
-let ProjectRootDocManager
-const ProjectEntityHandler = require('./ProjectEntityHandler')
-const ProjectEntityUpdateHandler = require('./ProjectEntityUpdateHandler')
-const ProjectGetter = require('./ProjectGetter')
-const DocumentHelper = require('../Documents/DocumentHelper')
-const Path = require('path')
-const fs = require('fs')
-const async = require('async')
-const globby = require('globby')
-const _ = require('lodash')
-const { promisifyAll } = require('@overleaf/promise-utils')
-const logger = require('@overleaf/logger')
-const {
-  BackgroundTaskTracker,
-} = require('../../infrastructure/GracefulShutdown')
+import ProjectEntityHandler from './ProjectEntityHandler.mjs'
+import ProjectEntityUpdateHandler from './ProjectEntityUpdateHandler.mjs'
+import ProjectGetter from './ProjectGetter.mjs'
+import DocumentHelper from '../Documents/DocumentHelper.js'
+import Path from 'node:path'
+import fs from 'node:fs'
+import async from 'async'
+import globby from 'globby'
+import _ from 'lodash'
+import { promisifyAll } from '@overleaf/promise-utils'
+import logger from '@overleaf/logger'
+import { BackgroundTaskTracker } from '../../infrastructure/GracefulShutdown.js'
 
 const rootDocResets = new BackgroundTaskTracker('root doc resets')
-
-module.exports = ProjectRootDocManager = {
+const ProjectRootDocManager = {
   setRootDocAutomaticallyInBackground(projectId) {
     rootDocResets.add()
     setTimeout(async () => {
@@ -332,10 +328,11 @@ module.exports = ProjectRootDocManager = {
   },
 }
 
-module.exports = ProjectRootDocManager
-module.exports.promises = promisifyAll(module.exports, {
+ProjectRootDocManager.promises = promisifyAll(ProjectRootDocManager, {
   without: ['_rootDocSort', 'setRootDocAutomaticallyInBackground'],
   multiResult: {
     findRootDocFileFromDirectory: ['path', 'content'],
   },
 })
+
+export default ProjectRootDocManager

+ 11 - 13
services/web/app/src/Features/Subscription/LimitationsManager.mjs

@@ -1,17 +1,15 @@
 // @ts-check
 
-const logger = require('@overleaf/logger')
-const ProjectGetter = require('../Project/ProjectGetter')
-const UserGetter = require('../User/UserGetter')
-const SubscriptionLocator = require('./SubscriptionLocator')
-const Settings = require('@overleaf/settings')
-const CollaboratorsGetter = require('../Collaborators/CollaboratorsGetter')
-const CollaboratorsInvitesGetter = require('../Collaborators/CollaboratorsInviteGetter')
-const PrivilegeLevels = require('../Authorization/PrivilegeLevels')
-const {
-  callbackify,
-  callbackifyMultiResult,
-} = require('@overleaf/promise-utils')
+import logger from '@overleaf/logger'
+
+import ProjectGetter from '../Project/ProjectGetter.mjs'
+import UserGetter from '../User/UserGetter.js'
+import SubscriptionLocator from './SubscriptionLocator.js'
+import Settings from '@overleaf/settings'
+import CollaboratorsGetter from '../Collaborators/CollaboratorsGetter.mjs'
+import CollaboratorsInvitesGetter from '../Collaborators/CollaboratorsInviteGetter.js'
+import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'
+import { callbackify, callbackifyMultiResult } from '@overleaf/promise-utils'
 
 async function allowedNumberOfCollaboratorsInProject(projectId) {
   const project = await ProjectGetter.promises.getProject(projectId, {
@@ -216,4 +214,4 @@ const LimitationsManager = {
   },
 }
 
-module.exports = LimitationsManager
+export default LimitationsManager

+ 15 - 14
services/web/app/src/Features/Subscription/SubscriptionHandler.mjs

@@ -1,18 +1,19 @@
 // @ts-check
 
-const RecurlyWrapper = require('./RecurlyWrapper')
-const RecurlyClient = require('./RecurlyClient')
-const { User } = require('../../models/User')
-const logger = require('@overleaf/logger')
-const SubscriptionHelper = require('./SubscriptionHelper')
-const SubscriptionUpdater = require('./SubscriptionUpdater')
-const SubscriptionLocator = require('./SubscriptionLocator')
-const LimitationsManager = require('./LimitationsManager')
-const EmailHandler = require('../Email/EmailHandler')
-const { callbackify } = require('@overleaf/promise-utils')
-const UserUpdater = require('../User/UserUpdater')
-const { IndeterminateInvoiceError } = require('../Errors/Errors')
-const Modules = require('../../infrastructure/Modules')
+import RecurlyWrapper from './RecurlyWrapper.js'
+
+import RecurlyClient from './RecurlyClient.js'
+import { User } from '../../models/User.js'
+import logger from '@overleaf/logger'
+import SubscriptionHelper from './SubscriptionHelper.js'
+import SubscriptionUpdater from './SubscriptionUpdater.js'
+import SubscriptionLocator from './SubscriptionLocator.js'
+import LimitationsManager from './LimitationsManager.mjs'
+import EmailHandler from '../Email/EmailHandler.js'
+import { callbackify } from '@overleaf/promise-utils'
+import UserUpdater from '../User/UserUpdater.js'
+import { IndeterminateInvoiceError } from '../Errors/Errors.js'
+import Modules from '../../infrastructure/Modules.js'
 
 /**
  * @import { PaymentProviderSubscriptionChange } from './PaymentProviderEntities'
@@ -415,7 +416,7 @@ async function setSubscriptionRestorePoint(userId) {
   )
 }
 
-module.exports = {
+export default {
   validateNoSubscriptionInRecurly: callbackify(validateNoSubscriptionInRecurly),
   createSubscription: callbackify(createSubscription),
   previewSubscriptionChange: callbackify(previewSubscriptionChange),

+ 20 - 26
services/web/app/src/Features/Subscription/TeamInvitesHandler.mjs

@@ -1,28 +1,22 @@
-const logger = require('@overleaf/logger')
-const crypto = require('crypto')
-
-const settings = require('@overleaf/settings')
-const Modules = require('../../infrastructure/Modules')
-const { ObjectId } = require('mongodb-legacy')
-
-const { Subscription } = require('../../models/Subscription')
-const { SSOConfig } = require('../../models/SSOConfig')
-
-const UserGetter = require('../User/UserGetter')
-const SubscriptionLocator = require('./SubscriptionLocator')
-const SubscriptionUpdater = require('./SubscriptionUpdater')
-const LimitationsManager = require('./LimitationsManager')
-
-const EmailHandler = require('../Email/EmailHandler')
-const EmailHelper = require('../Helpers/EmailHelper')
-
-const Errors = require('../Errors/Errors')
-const {
-  callbackify,
-  callbackifyMultiResult,
-} = require('@overleaf/promise-utils')
-const NotificationsBuilder = require('../Notifications/NotificationsBuilder')
-const RecurlyClient = require('./RecurlyClient')
+import logger from '@overleaf/logger'
+import crypto from 'node:crypto'
+import settings from '@overleaf/settings'
+import Modules from '../../infrastructure/Modules.js'
+import mongodb from 'mongodb-legacy'
+import { Subscription } from '../../models/Subscription.js'
+import { SSOConfig } from '../../models/SSOConfig.js'
+import UserGetter from '../User/UserGetter.js'
+import SubscriptionLocator from './SubscriptionLocator.js'
+import SubscriptionUpdater from './SubscriptionUpdater.js'
+import LimitationsManager from './LimitationsManager.mjs'
+import EmailHandler from '../Email/EmailHandler.js'
+import EmailHelper from '../Helpers/EmailHelper.js'
+import Errors from '../Errors/Errors.js'
+import { callbackify, callbackifyMultiResult } from '@overleaf/promise-utils'
+import NotificationsBuilder from '../Notifications/NotificationsBuilder.js'
+import RecurlyClient from './RecurlyClient.js'
+
+const { ObjectId } = mongodb
 
 async function getInvite(token) {
   const subscription = await Subscription.findOne({
@@ -404,7 +398,7 @@ function _getInviterName(inviter) {
   return inviterName
 }
 
-module.exports = {
+export default {
   getInvite: callbackifyMultiResult(getInvite, ['invite', 'subscription']),
   createInvite: callbackify(createInvite),
   importInvite: callbackify(importInvite),

+ 19 - 18
services/web/app/src/Features/Templates/TemplatesManager.mjs

@@ -1,23 +1,24 @@
-const { Project } = require('../../models/Project')
-const ProjectDetailsHandler = require('../Project/ProjectDetailsHandler')
-const ProjectOptionsHandler =
-  require('../Project/ProjectOptionsHandler').promises
-const ProjectRootDocManager =
-  require('../Project/ProjectRootDocManager').promises
-const ProjectUploadManager = require('../Uploads/ProjectUploadManager')
-const fs = require('fs')
-const util = require('util')
-const logger = require('@overleaf/logger')
-const {
+import { Project } from '../../models/Project.js'
+import ProjectDetailsHandler from '../Project/ProjectDetailsHandler.mjs'
+import ProjectOptionsHandlerModule from '../Project/ProjectOptionsHandler.js'
+import ProjectRootDocManagerModule from '../Project/ProjectRootDocManager.mjs'
+import ProjectUploadManager from '../Uploads/ProjectUploadManager.mjs'
+import fs from 'node:fs'
+import util from 'node:util'
+import logger from '@overleaf/logger'
+import {
   fetchJson,
   fetchStreamWithResponse,
   RequestFailedError,
-} = require('@overleaf/fetch-utils')
-const settings = require('@overleaf/settings')
-const crypto = require('crypto')
-const Errors = require('../Errors/Errors')
-const { pipeline } = require('stream/promises')
-const ClsiCacheManager = require('../Compile/ClsiCacheManager')
+} from '@overleaf/fetch-utils'
+import settings from '@overleaf/settings'
+import crypto from 'node:crypto'
+import Errors from '../Errors/Errors.js'
+import { pipeline } from 'node:stream/promises'
+import ClsiCacheManager from '../Compile/ClsiCacheManager.mjs'
+
+const { promises: ProjectRootDocManager } = ProjectRootDocManagerModule
+const { promises: ProjectOptionsHandler } = ProjectOptionsHandlerModule
 
 const TemplatesManager = {
   async createProjectFromV1Template(
@@ -144,7 +145,7 @@ const TemplatesManager = {
   },
 }
 
-module.exports = {
+export default {
   promises: TemplatesManager,
   createProjectFromV1Template: util.callbackify(
     TemplatesManager.createProjectFromV1Template

+ 9 - 9
services/web/app/src/Features/ThirdPartyDataStore/TpdsProjectFlusher.mjs

@@ -1,13 +1,13 @@
-const { callbackify } = require('util')
-const logger = require('@overleaf/logger')
-const DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler')
-const ProjectGetter = require('../Project/ProjectGetter')
-const ProjectEntityHandler = require('../Project/ProjectEntityHandler')
-const { Project } = require('../../models/Project')
-const TpdsUpdateSender = require('./TpdsUpdateSender')
-const OError = require('@overleaf/o-error')
+import { callbackify } from 'node:util'
+import logger from '@overleaf/logger'
+import DocumentUpdaterHandler from '../DocumentUpdater/DocumentUpdaterHandler.mjs'
+import ProjectGetter from '../Project/ProjectGetter.mjs'
+import ProjectEntityHandler from '../Project/ProjectEntityHandler.mjs'
+import { Project } from '../../models/Project.js'
+import TpdsUpdateSender from './TpdsUpdateSender.mjs'
+import OError from '@overleaf/o-error'
 
-module.exports = {
+export default {
   flushProjectToTpds: callbackify(flushProjectToTpds),
   deferProjectFlushToTpds: callbackify(deferProjectFlushToTpds),
   flushProjectToTpdsIfNeeded: callbackify(flushProjectToTpdsIfNeeded),

+ 16 - 13
services/web/app/src/Features/ThirdPartyDataStore/TpdsUpdateSender.mjs

@@ -1,15 +1,18 @@
-const { ObjectId } = require('mongodb-legacy')
-const _ = require('lodash')
-const { callbackify } = require('util')
-const logger = require('@overleaf/logger')
-const metrics = require('@overleaf/metrics')
-const Path = require('path')
-const { fetchNothing } = require('@overleaf/fetch-utils')
-const settings = require('@overleaf/settings')
-
-const CollaboratorsGetter =
-  require('../Collaborators/CollaboratorsGetter').promises
-const UserGetter = require('../User/UserGetter').promises
+import mongodb from 'mongodb-legacy'
+import _ from 'lodash'
+import { callbackify } from 'node:util'
+import logger from '@overleaf/logger'
+import metrics from '@overleaf/metrics'
+import Path from 'node:path'
+import { fetchNothing } from '@overleaf/fetch-utils'
+import settings from '@overleaf/settings'
+import CollaboratorsGetterModule from '../Collaborators/CollaboratorsGetter.mjs'
+import UserGetterModule from '../User/UserGetter.js'
+
+const { promises: UserGetter } = UserGetterModule
+const { promises: CollaboratorsGetter } = CollaboratorsGetterModule
+
+const { ObjectId } = mongodb
 
 const tpdsUrl = _.get(settings, ['apis', 'thirdPartyDataStore', 'url'])
 
@@ -280,4 +283,4 @@ const TpdsUpdateSender = {
   },
 }
 
-module.exports = TpdsUpdateSender
+export default TpdsUpdateSender

+ 9 - 9
services/web/app/src/Features/Uploads/FileSystemImportManager.mjs

@@ -1,13 +1,13 @@
-const fs = require('fs')
-const Path = require('path')
-const { callbackify } = require('util')
-const EditorController = require('../Editor/EditorController')
-const Errors = require('../Errors/Errors')
-const FileTypeManager = require('./FileTypeManager')
-const SafePath = require('../Project/SafePath')
-const logger = require('@overleaf/logger')
+import fs from 'node:fs'
+import Path from 'node:path'
+import { callbackify } from 'node:util'
+import EditorController from '../Editor/EditorController.mjs'
+import Errors from '../Errors/Errors.js'
+import FileTypeManager from './FileTypeManager.js'
+import SafePath from '../Project/SafePath.js'
+import logger from '@overleaf/logger'
 
-module.exports = {
+export default {
   addEntity: callbackify(addEntity),
   importDir: callbackify(importDir),
   importFile: callbackify(importDir),

+ 19 - 19
services/web/app/src/Features/Uploads/ProjectUploadManager.mjs

@@ -1,23 +1,23 @@
-const Path = require('path')
-const fs = require('fs')
-const { callbackify } = require('util')
-const ArchiveManager = require('./ArchiveManager')
-const { Doc } = require('../../models/Doc')
-const DocstoreManager = require('../Docstore/DocstoreManager')
-const DocumentHelper = require('../Documents/DocumentHelper')
-const DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler')
-const FileStoreHandler = require('../FileStore/FileStoreHandler')
-const FileSystemImportManager = require('./FileSystemImportManager')
-const ProjectCreationHandler = require('../Project/ProjectCreationHandler')
-const ProjectEntityMongoUpdateHandler = require('../Project/ProjectEntityMongoUpdateHandler')
-const ProjectRootDocManager = require('../Project/ProjectRootDocManager')
-const ProjectDetailsHandler = require('../Project/ProjectDetailsHandler')
-const ProjectDeleter = require('../Project/ProjectDeleter')
-const TpdsProjectFlusher = require('../ThirdPartyDataStore/TpdsProjectFlusher')
-const logger = require('@overleaf/logger')
-const OError = require('@overleaf/o-error')
+import Path from 'node:path'
+import fs from 'node:fs'
+import { callbackify } from 'node:util'
+import ArchiveManager from './ArchiveManager.js'
+import { Doc } from '../../models/Doc.js'
+import DocstoreManager from '../Docstore/DocstoreManager.js'
+import DocumentHelper from '../Documents/DocumentHelper.js'
+import DocumentUpdaterHandler from '../DocumentUpdater/DocumentUpdaterHandler.mjs'
+import FileStoreHandler from '../FileStore/FileStoreHandler.mjs'
+import FileSystemImportManager from './FileSystemImportManager.mjs'
+import ProjectCreationHandler from '../Project/ProjectCreationHandler.mjs'
+import ProjectEntityMongoUpdateHandler from '../Project/ProjectEntityMongoUpdateHandler.mjs'
+import ProjectRootDocManager from '../Project/ProjectRootDocManager.mjs'
+import ProjectDetailsHandler from '../Project/ProjectDetailsHandler.mjs'
+import ProjectDeleter from '../Project/ProjectDeleter.mjs'
+import TpdsProjectFlusher from '../ThirdPartyDataStore/TpdsProjectFlusher.mjs'
+import logger from '@overleaf/logger'
+import OError from '@overleaf/o-error'
 
-module.exports = {
+export default {
   createProjectFromZipArchive: callbackify(createProjectFromZipArchive),
   createProjectFromZipArchiveWithName: callbackify(
     createProjectFromZipArchiveWithName

+ 21 - 21
services/web/app/src/Features/User/UserDeleter.mjs

@@ -1,25 +1,25 @@
-const { callbackify } = require('util')
-const logger = require('@overleaf/logger')
-const Settings = require('@overleaf/settings')
-const { User } = require('../../models/User')
-const { DeletedUser } = require('../../models/DeletedUser')
-const { UserAuditLogEntry } = require('../../models/UserAuditLogEntry')
-const { Feedback } = require('../../models/Feedback')
-const NewsletterManager = require('../Newsletter/NewsletterManager')
-const ProjectDeleter = require('../Project/ProjectDeleter')
-const SubscriptionHandler = require('../Subscription/SubscriptionHandler')
-const SubscriptionUpdater = require('../Subscription/SubscriptionUpdater')
-const SubscriptionLocator = require('../Subscription/SubscriptionLocator')
-const UserMembershipsHandler = require('../UserMembership/UserMembershipsHandler')
-const UserSessionsManager = require('./UserSessionsManager')
-const UserAuditLogHandler = require('./UserAuditLogHandler')
-const InstitutionsAPI = require('../Institutions/InstitutionsAPI')
-const Modules = require('../../infrastructure/Modules')
-const Errors = require('../Errors/Errors')
-const OnboardingDataCollectionManager = require('../OnboardingDataCollection/OnboardingDataCollectionManager')
-const EmailHandler = require('../Email/EmailHandler')
+import { callbackify } from 'node:util'
+import logger from '@overleaf/logger'
+import Settings from '@overleaf/settings'
+import { User } from '../../models/User.js'
+import { DeletedUser } from '../../models/DeletedUser.js'
+import { UserAuditLogEntry } from '../../models/UserAuditLogEntry.js'
+import { Feedback } from '../../models/Feedback.js'
+import NewsletterManager from '../Newsletter/NewsletterManager.js'
+import ProjectDeleter from '../Project/ProjectDeleter.mjs'
+import SubscriptionHandler from '../Subscription/SubscriptionHandler.mjs'
+import SubscriptionUpdater from '../Subscription/SubscriptionUpdater.js'
+import SubscriptionLocator from '../Subscription/SubscriptionLocator.js'
+import UserMembershipsHandler from '../UserMembership/UserMembershipsHandler.js'
+import UserSessionsManager from './UserSessionsManager.js'
+import UserAuditLogHandler from './UserAuditLogHandler.js'
+import InstitutionsAPI from '../Institutions/InstitutionsAPI.js'
+import Modules from '../../infrastructure/Modules.js'
+import Errors from '../Errors/Errors.js'
+import OnboardingDataCollectionManager from '../OnboardingDataCollection/OnboardingDataCollectionManager.js'
+import EmailHandler from '../Email/EmailHandler.js'
 
-module.exports = {
+export default {
   deleteUser: callbackify(deleteUser),
   deleteMongoUser: callbackify(deleteMongoUser),
   expireDeletedUser: callbackify(expireDeletedUser),

+ 4 - 7
services/web/app/src/Features/User/UserHandler.mjs

@@ -1,9 +1,6 @@
-const { callbackify } = require('util')
-const TeamInvitesHandler = require('../Subscription/TeamInvitesHandler')
-const {
-  db,
-  READ_PREFERENCE_SECONDARY,
-} = require('../../infrastructure/mongodb')
+import { callbackify } from 'node:util'
+import TeamInvitesHandler from '../Subscription/TeamInvitesHandler.mjs'
+import { db, READ_PREFERENCE_SECONDARY } from '../../infrastructure/mongodb.js'
 
 async function populateTeamInvites(user) {
   return await TeamInvitesHandler.promises.createTeamInvitesForLegacyInvitedEmail(
@@ -20,7 +17,7 @@ async function countActiveUsers() {
   )
 }
 
-module.exports = {
+export default {
   populateTeamInvites: callbackify(populateTeamInvites),
   countActiveUsers: callbackify(countActiveUsers),
   promises: {

+ 4 - 3
services/web/app/src/Features/UserMembership/UserMembershipMiddleware.mjs

@@ -4,15 +4,16 @@ import { expressify } from '@overleaf/promise-utils'
 
 import async from 'async'
 import UserMembershipAuthorization from './UserMembershipAuthorization.mjs'
-import AuthenticationController from '../Authentication/AuthenticationController.js'
+import AuthenticationController from '../Authentication/AuthenticationController.mjs'
 import UserMembershipHandler from './UserMembershipHandler.mjs'
 import EntityConfigs from './UserMembershipEntityConfigs.js'
 import Errors from '../Errors/Errors.js'
 import HttpErrorHandler from '../Errors/HttpErrorHandler.js'
-import TemplatesManager from '../Templates/TemplatesManager.js'
+import TemplatesManager from '../Templates/TemplatesManager.mjs'
 import { z, zz, validateReq } from '../../infrastructure/Validation.js'
-import { useAdminCapabilities } from '../Helpers/AdminAuthorizationHelper.js'
+import AdminAuthorizationHelper from '../Helpers/AdminAuthorizationHelper.mjs'
 
+const { useAdminCapabilities } = AdminAuthorizationHelper
 // set of middleware arrays or functions that checks user access to an entity
 // (publisher, institution, group, template, etc.)
 const UserMembershipMiddleware = {