ソースを参照

Merge pull request #29597 from overleaf/ar-last-features-esm-conversion

[web] last features esm conversion

GitOrigin-RevId: a35ab995bf654f1cdfe0e0062d8806761ecccf2d
Andrew Rumble 8 ヶ月 前
コミット
beb6f6d484
100 ファイル変更212 行追加200 行削除
  1. 2 0
      services/web/.eslintrc.js
  2. 1 1
      services/web/app/src/Features/Analytics/AnalyticsController.mjs
  3. 1 1
      services/web/app/src/Features/Analytics/AnalyticsManager.mjs
  4. 2 2
      services/web/app/src/Features/Authentication/AuthenticationController.mjs
  5. 11 11
      services/web/app/src/Features/Authentication/AuthenticationErrors.mjs
  6. 1 1
      services/web/app/src/Features/Authentication/AuthenticationManager.mjs
  7. 2 2
      services/web/app/src/Features/Authorization/AuthorizationManager.mjs
  8. 1 1
      services/web/app/src/Features/Authorization/PermissionsController.mjs
  9. 1 1
      services/web/app/src/Features/Authorization/PrivilegeLevels.mjs
  10. 1 1
      services/web/app/src/Features/BrandVariations/BrandVariationsHandler.mjs
  11. 2 2
      services/web/app/src/Features/Collaborators/CollaboratorsController.mjs
  12. 1 1
      services/web/app/src/Features/Collaborators/CollaboratorsGetter.mjs
  13. 1 1
      services/web/app/src/Features/Collaborators/CollaboratorsHandler.mjs
  14. 1 1
      services/web/app/src/Features/Collaborators/CollaboratorsInviteController.mjs
  15. 1 1
      services/web/app/src/Features/Collaborators/CollaboratorsInviteGetter.mjs
  16. 1 1
      services/web/app/src/Features/Collaborators/CollaboratorsInviteHandler.mjs
  17. 1 1
      services/web/app/src/Features/Collaborators/OwnershipTransferHandler.mjs
  18. 1 1
      services/web/app/src/Features/Compile/ClsiCacheHandler.mjs
  19. 1 1
      services/web/app/src/Features/Compile/ClsiCacheManager.mjs
  20. 1 1
      services/web/app/src/Features/Compile/CompileController.mjs
  21. 1 1
      services/web/app/src/Features/Editor/EditorHttpController.mjs
  22. 2 2
      services/web/app/src/Features/Email/Bodies/NoCTAEmailBody.mjs
  23. 2 2
      services/web/app/src/Features/Email/Bodies/cta-email.mjs
  24. 4 4
      services/web/app/src/Features/Email/EmailBuilder.mjs
  25. 1 1
      services/web/app/src/Features/Email/EmailHandler.mjs
  26. 2 2
      services/web/app/src/Features/Email/EmailMessageHelper.mjs
  27. 3 3
      services/web/app/src/Features/Email/Layouts/BaseWithHeaderEmailLayout.mjs
  28. 6 4
      services/web/app/src/Features/Helpers/Mongo.mjs
  29. 1 1
      services/web/app/src/Features/History/HistoryController.mjs
  30. 3 3
      services/web/app/src/Features/Project/ProjectController.mjs
  31. 1 1
      services/web/app/src/Features/Project/ProjectCreationHandler.mjs
  32. 1 1
      services/web/app/src/Features/Project/ProjectDetailsHandler.mjs
  33. 3 1
      services/web/app/src/Features/Project/ProjectGetter.mjs
  34. 2 2
      services/web/app/src/Features/Project/ProjectListController.mjs
  35. 4 4
      services/web/app/src/Features/Security/LoginRateLimiter.mjs
  36. 1 1
      services/web/app/src/Features/Security/RateLimiterMiddleware.mjs
  37. 1 1
      services/web/app/src/Features/SplitTests/SplitTestHandler.mjs
  38. 1 1
      services/web/app/src/Features/StaticPages/HomeController.mjs
  39. 6 6
      services/web/app/src/Features/Subscription/AiHelper.mjs
  40. 18 17
      services/web/app/src/Features/Subscription/Errors.mjs
  41. 2 2
      services/web/app/src/Features/Subscription/FeaturesUpdater.mjs
  42. 5 5
      services/web/app/src/Features/Subscription/GroupPlansData.mjs
  43. 1 1
      services/web/app/src/Features/Subscription/LimitationsManager.mjs
  44. 2 2
      services/web/app/src/Features/Subscription/PaymentProviderEntities.mjs
  45. 2 2
      services/web/app/src/Features/Subscription/RecurlyClient.mjs
  46. 1 1
      services/web/app/src/Features/Subscription/RecurlyEventHandler.mjs
  47. 1 1
      services/web/app/src/Features/Subscription/RecurlyWrapper.mjs
  48. 3 3
      services/web/app/src/Features/Subscription/SubscriptionController.mjs
  49. 1 1
      services/web/app/src/Features/Subscription/SubscriptionEmailBuilder.mjs
  50. 1 1
      services/web/app/src/Features/Subscription/SubscriptionGroupController.mjs
  51. 2 2
      services/web/app/src/Features/Subscription/SubscriptionGroupHandler.mjs
  52. 2 2
      services/web/app/src/Features/Subscription/SubscriptionHelper.mjs
  53. 2 2
      services/web/app/src/Features/Subscription/SubscriptionLocator.mjs
  54. 1 1
      services/web/app/src/Features/Subscription/SubscriptionUpdater.mjs
  55. 1 1
      services/web/app/src/Features/Subscription/SubscriptionViewModelBuilder.mjs
  56. 1 1
      services/web/app/src/Features/TokenAccess/TokenAccessController.mjs
  57. 3 3
      services/web/app/src/Features/TokenAccess/TokenAccessHandler.mjs
  58. 5 5
      services/web/app/src/Features/TokenGenerator/TokenGenerator.mjs
  59. 5 5
      services/web/app/src/Features/Uploads/ArchiveErrors.mjs
  60. 1 1
      services/web/app/src/Features/Uploads/ArchiveManager.mjs
  61. 1 1
      services/web/app/src/Features/Uploads/ProjectUploadController.mjs
  62. 1 1
      services/web/app/src/Features/User/UserController.mjs
  63. 1 1
      services/web/app/src/Features/User/UserCreator.mjs
  64. 1 1
      services/web/app/src/Features/User/UserEmailsController.mjs
  65. 3 2
      services/web/app/src/Features/User/UserGetter.mjs
  66. 1 1
      services/web/app/src/Features/User/UserOnboardingEmailManager.mjs
  67. 1 1
      services/web/app/src/Features/User/UserPagesController.mjs
  68. 1 1
      services/web/app/src/Features/User/UserPostRegistrationAnalyticsManager.mjs
  69. 4 2
      services/web/app/src/Features/User/UserUpdater.mjs
  70. 3 1
      services/web/app/src/Features/UserMembership/UserMembershipViewModel.mjs
  71. 6 5
      services/web/app/src/Features/V1/V1Api.mjs
  72. 1 1
      services/web/app/src/Features/V1/V1Handler.mjs
  73. 1 1
      services/web/app/src/infrastructure/ExpressLocals.mjs
  74. 3 3
      services/web/app/src/infrastructure/Features.mjs
  75. 2 2
      services/web/app/src/infrastructure/QueueWorkers.mjs
  76. 5 5
      services/web/app/src/infrastructure/Queues.mjs
  77. 1 1
      services/web/app/src/infrastructure/Server.mjs
  78. 1 1
      services/web/app/src/infrastructure/SiteAdminHandler.mjs
  79. 1 1
      services/web/app/src/models/User.mjs
  80. 1 1
      services/web/app/src/router.mjs
  81. 2 1
      services/web/scripts/backfill_mixpanel_user_properties.mjs
  82. 1 1
      services/web/scripts/regenerate_duplicate_referral_ids.mjs
  83. 1 1
      services/web/test/acceptance/src/ActiveUsersMetricTests.mjs
  84. 1 1
      services/web/test/acceptance/src/AddSecondaryEmailTests.mjs
  85. 1 1
      services/web/test/acceptance/src/AuthorizationTests.mjs
  86. 1 1
      services/web/test/acceptance/src/DeletionTests.mjs
  87. 1 1
      services/web/test/acceptance/src/Init.mjs
  88. 3 4
      services/web/test/acceptance/src/MongoHelper.mjs
  89. 1 1
      services/web/test/acceptance/src/PrimaryEmailCheckTests.mjs
  90. 1 1
      services/web/test/acceptance/src/ProjectCRUDTests.mjs
  91. 1 1
      services/web/test/acceptance/src/ProjectInviteTests.mjs
  92. 1 1
      services/web/test/acceptance/src/RegistrationTests.mjs
  93. 1 1
      services/web/test/acceptance/src/SettingsTests.mjs
  94. 1 1
      services/web/test/acceptance/src/UserHelperTests.mjs
  95. 1 1
      services/web/test/smoke/src/steps/001_clearRateLimits.mjs
  96. 1 4
      services/web/test/unit/bootstrap.js
  97. 3 3
      services/web/test/unit/src/Analytics/AnalyticsController.test.mjs
  98. 5 5
      services/web/test/unit/src/Analytics/AnalyticsManager.test.mjs
  99. 4 4
      services/web/test/unit/src/Analytics/AnalyticsUTMTrackingMiddleware.test.mjs
  100. 3 1
      services/web/test/unit/src/Analytics/EmailChangeHelpers.test.mjs

+ 2 - 0
services/web/.eslintrc.js

@@ -137,6 +137,8 @@ module.exports = {
         'app.mjs',
         'app.mjs',
         'scripts/**/*.mjs',
         'scripts/**/*.mjs',
         'migrations/**/*.mjs',
         'migrations/**/*.mjs',
+        'test/acceptance/src/**/*.mjs',
+        'test/unit/src/**/*.mjs',
       ],
       ],
       excludedFiles: [
       excludedFiles: [
         // migration template file
         // migration template file

+ 1 - 1
services/web/app/src/Features/Analytics/AnalyticsController.mjs

@@ -2,7 +2,7 @@ import metrics from '@overleaf/metrics'
 import AnalyticsManager from './AnalyticsManager.mjs'
 import AnalyticsManager from './AnalyticsManager.mjs'
 import SessionManager from '../Authentication/SessionManager.mjs'
 import SessionManager from '../Authentication/SessionManager.mjs'
 import GeoIpLookup from '../../infrastructure/GeoIpLookup.mjs'
 import GeoIpLookup from '../../infrastructure/GeoIpLookup.mjs'
-import Features from '../../infrastructure/Features.js'
+import Features from '../../infrastructure/Features.mjs'
 import { expressify } from '@overleaf/promise-utils'
 import { expressify } from '@overleaf/promise-utils'
 import AccountMappingHelper from './AccountMappingHelper.mjs'
 import AccountMappingHelper from './AccountMappingHelper.mjs'
 
 

+ 1 - 1
services/web/app/src/Features/Analytics/AnalyticsManager.mjs

@@ -2,7 +2,7 @@ import SessionManager from '../Authentication/SessionManager.mjs'
 import UserAnalyticsIdCache from './UserAnalyticsIdCache.mjs'
 import UserAnalyticsIdCache from './UserAnalyticsIdCache.mjs'
 import Settings from '@overleaf/settings'
 import Settings from '@overleaf/settings'
 import Metrics from '../../infrastructure/Metrics.js'
 import Metrics from '../../infrastructure/Metrics.js'
-import Queues from '../../infrastructure/Queues.js'
+import Queues from '../../infrastructure/Queues.mjs'
 import crypto, { createHash } from 'node:crypto'
 import crypto, { createHash } from 'node:crypto'
 import _ from 'lodash'
 import _ from 'lodash'
 import { expressify } from '@overleaf/promise-utils'
 import { expressify } from '@overleaf/promise-utils'

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

@@ -1,7 +1,7 @@
 import AuthenticationManager from './AuthenticationManager.mjs'
 import AuthenticationManager from './AuthenticationManager.mjs'
 import SessionManager from './SessionManager.mjs'
 import SessionManager from './SessionManager.mjs'
 import OError from '@overleaf/o-error'
 import OError from '@overleaf/o-error'
-import LoginRateLimiter from '../Security/LoginRateLimiter.js'
+import LoginRateLimiter from '../Security/LoginRateLimiter.mjs'
 import UserUpdater from '../User/UserUpdater.mjs'
 import UserUpdater from '../User/UserUpdater.mjs'
 import Metrics from '@overleaf/metrics'
 import Metrics from '@overleaf/metrics'
 import logger from '@overleaf/logger'
 import logger from '@overleaf/logger'
@@ -23,7 +23,7 @@ import { acceptsJson } from '../../infrastructure/RequestContentTypeDetection.js
 import AdminAuthorizationHelper from '../Helpers/AdminAuthorizationHelper.mjs'
 import AdminAuthorizationHelper from '../Helpers/AdminAuthorizationHelper.mjs'
 import Modules from '../../infrastructure/Modules.js'
 import Modules from '../../infrastructure/Modules.js'
 import { expressify, promisify } from '@overleaf/promise-utils'
 import { expressify, promisify } from '@overleaf/promise-utils'
-import { handleAuthenticateErrors } from './AuthenticationErrors.js'
+import { handleAuthenticateErrors } from './AuthenticationErrors.mjs'
 import EmailHelper from '../Helpers/EmailHelper.mjs'
 import EmailHelper from '../Helpers/EmailHelper.mjs'
 
 
 const { hasAdminAccess } = AdminAuthorizationHelper
 const { hasAdminAccess } = AdminAuthorizationHelper

+ 11 - 11
services/web/app/src/Features/Authentication/AuthenticationErrors.js → services/web/app/src/Features/Authentication/AuthenticationErrors.mjs

@@ -1,15 +1,15 @@
-const Metrics = require('@overleaf/metrics')
-const OError = require('@overleaf/o-error')
-const Settings = require('@overleaf/settings')
-const Errors = require('../Errors/Errors')
+import Metrics from '@overleaf/metrics'
+import OError from '@overleaf/o-error'
+import Settings from '@overleaf/settings'
+import Errors from '../Errors/Errors.js'
 
 
-class InvalidEmailError extends Errors.BackwardCompatibleError {}
-class InvalidPasswordError extends Errors.BackwardCompatibleError {}
-class ParallelLoginError extends Errors.BackwardCompatibleError {}
-class PasswordMustBeDifferentError extends Errors.BackwardCompatibleError {}
-class PasswordReusedError extends Errors.BackwardCompatibleError {}
+export class InvalidEmailError extends Errors.BackwardCompatibleError {}
+export class InvalidPasswordError extends Errors.BackwardCompatibleError {}
+export class ParallelLoginError extends Errors.BackwardCompatibleError {}
+export class PasswordMustBeDifferentError extends Errors.BackwardCompatibleError {}
+export class PasswordReusedError extends Errors.BackwardCompatibleError {}
 
 
-function handleAuthenticateErrors(error, req) {
+export function handleAuthenticateErrors(error, req) {
   if (error.message === 'password is too long') {
   if (error.message === 'password is too long') {
     Metrics.inc('login_failure_reason', 1, {
     Metrics.inc('login_failure_reason', 1, {
       status: 'password_is_too_long',
       status: 'password_is_too_long',
@@ -48,7 +48,7 @@ function handleAuthenticateErrors(error, req) {
   throw error
   throw error
 }
 }
 
 
-module.exports = {
+export default {
   InvalidEmailError,
   InvalidEmailError,
   InvalidPasswordError,
   InvalidPasswordError,
   ParallelLoginError,
   ParallelLoginError,

+ 1 - 1
services/web/app/src/Features/Authentication/AuthenticationManager.mjs

@@ -10,7 +10,7 @@ import {
   ParallelLoginError,
   ParallelLoginError,
   PasswordMustBeDifferentError,
   PasswordMustBeDifferentError,
   PasswordReusedError,
   PasswordReusedError,
-} from './AuthenticationErrors.js'
+} from './AuthenticationErrors.mjs'
 
 
 import { callbackify, callbackifyMultiResult } from '@overleaf/promise-utils'
 import { callbackify, callbackifyMultiResult } from '@overleaf/promise-utils'
 import HaveIBeenPwned from './HaveIBeenPwned.mjs'
 import HaveIBeenPwned from './HaveIBeenPwned.mjs'

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

@@ -1,11 +1,11 @@
 import { callbackify } from 'node:util'
 import { callbackify } from 'node:util'
 import mongodb from 'mongodb-legacy'
 import mongodb from 'mongodb-legacy'
-import Features from '../../infrastructure/Features.js'
+import Features from '../../infrastructure/Features.mjs'
 import CollaboratorsGetter from '../Collaborators/CollaboratorsGetter.mjs'
 import CollaboratorsGetter from '../Collaborators/CollaboratorsGetter.mjs'
 import CollaboratorsHandler from '../Collaborators/CollaboratorsHandler.mjs'
 import CollaboratorsHandler from '../Collaborators/CollaboratorsHandler.mjs'
 import ProjectGetter from '../Project/ProjectGetter.mjs'
 import ProjectGetter from '../Project/ProjectGetter.mjs'
 import { User } from '../../models/User.mjs'
 import { User } from '../../models/User.mjs'
-import PrivilegeLevels from './PrivilegeLevels.js'
+import PrivilegeLevels from './PrivilegeLevels.mjs'
 import TokenAccessHandler from '../TokenAccess/TokenAccessHandler.mjs'
 import TokenAccessHandler from '../TokenAccess/TokenAccessHandler.mjs'
 import PublicAccessLevels from './PublicAccessLevels.mjs'
 import PublicAccessLevels from './PublicAccessLevels.mjs'
 import Errors from '../Errors/Errors.js'
 import Errors from '../Errors/Errors.js'

+ 1 - 1
services/web/app/src/Features/Authorization/PermissionsController.mjs

@@ -3,7 +3,7 @@ import { ForbiddenError, UserNotFoundError } from '../Errors/Errors.js'
 import PermissionsManager from './PermissionsManager.mjs'
 import PermissionsManager from './PermissionsManager.mjs'
 import Modules from '../../infrastructure/Modules.js'
 import Modules from '../../infrastructure/Modules.js'
 import { expressify } from '@overleaf/promise-utils'
 import { expressify } from '@overleaf/promise-utils'
-import Features from '../../infrastructure/Features.js'
+import Features from '../../infrastructure/Features.mjs'
 
 
 /**
 /**
  * @typedef {(import('express').Request)} Request
  * @typedef {(import('express').Request)} Request

+ 1 - 1
services/web/app/src/Features/Authorization/PrivilegeLevels.js → services/web/app/src/Features/Authorization/PrivilegeLevels.mjs

@@ -9,4 +9,4 @@ const PrivilegeLevels = {
   OWNER: 'owner',
   OWNER: 'owner',
 }
 }
 
 
-module.exports = PrivilegeLevels
+export default PrivilegeLevels

+ 1 - 1
services/web/app/src/Features/BrandVariations/BrandVariationsHandler.mjs

@@ -2,7 +2,7 @@ import OError from '@overleaf/o-error'
 import { URL } from 'node:url'
 import { URL } from 'node:url'
 import settings from '@overleaf/settings'
 import settings from '@overleaf/settings'
 import logger from '@overleaf/logger'
 import logger from '@overleaf/logger'
-import V1Api from '../V1/V1Api.js'
+import V1Api from '../V1/V1Api.mjs'
 import sanitizeHtml from 'sanitize-html'
 import sanitizeHtml from 'sanitize-html'
 import { promisify } from '@overleaf/promise-utils'
 import { promisify } from '@overleaf/promise-utils'
 
 

+ 2 - 2
services/web/app/src/Features/Collaborators/CollaboratorsController.mjs

@@ -14,9 +14,9 @@ import AdminAuthorizationHelper from '../Helpers/AdminAuthorizationHelper.mjs'
 import TokenAccessHandler from '../TokenAccess/TokenAccessHandler.mjs'
 import TokenAccessHandler from '../TokenAccess/TokenAccessHandler.mjs'
 import ProjectAuditLogHandler from '../Project/ProjectAuditLogHandler.mjs'
 import ProjectAuditLogHandler from '../Project/ProjectAuditLogHandler.mjs'
 import LimitationsManager from '../Subscription/LimitationsManager.mjs'
 import LimitationsManager from '../Subscription/LimitationsManager.mjs'
-import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'
+import PrivilegeLevels from '../Authorization/PrivilegeLevels.mjs'
 import { z, zz, validateReq } from '../../infrastructure/Validation.js'
 import { z, zz, validateReq } from '../../infrastructure/Validation.js'
-import Features from '../../infrastructure/Features.js'
+import Features from '../../infrastructure/Features.mjs'
 
 
 const { hasAdminAccess } = AdminAuthorizationHelper
 const { hasAdminAccess } = AdminAuthorizationHelper
 const ObjectId = mongodb.ObjectId
 const ObjectId = mongodb.ObjectId

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

@@ -11,7 +11,7 @@ import PublicAccessLevels from '../Authorization/PublicAccessLevels.mjs'
 import Errors from '../Errors/Errors.js'
 import Errors from '../Errors/Errors.js'
 import ProjectEditorHandler from '../Project/ProjectEditorHandler.mjs'
 import ProjectEditorHandler from '../Project/ProjectEditorHandler.mjs'
 import Sources from '../Authorization/Sources.mjs'
 import Sources from '../Authorization/Sources.mjs'
-import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'
+import PrivilegeLevels from '../Authorization/PrivilegeLevels.mjs'
 
 
 const { ObjectId } = mongodb
 const { ObjectId } = mongodb
 
 

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

@@ -4,7 +4,7 @@ import { Project } from '../../models/Project.mjs'
 import ProjectGetter from '../Project/ProjectGetter.mjs'
 import ProjectGetter from '../Project/ProjectGetter.mjs'
 import logger from '@overleaf/logger'
 import logger from '@overleaf/logger'
 import ContactManager from '../Contacts/ContactManager.mjs'
 import ContactManager from '../Contacts/ContactManager.mjs'
-import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'
+import PrivilegeLevels from '../Authorization/PrivilegeLevels.mjs'
 import TpdsProjectFlusher from '../ThirdPartyDataStore/TpdsProjectFlusher.mjs'
 import TpdsProjectFlusher from '../ThirdPartyDataStore/TpdsProjectFlusher.mjs'
 import CollaboratorsGetter from './CollaboratorsGetter.mjs'
 import CollaboratorsGetter from './CollaboratorsGetter.mjs'
 import Errors from '../Errors/Errors.js'
 import Errors from '../Errors/Errors.js'

+ 1 - 1
services/web/app/src/Features/Collaborators/CollaboratorsInviteController.mjs

@@ -16,7 +16,7 @@ import { expressify } from '@overleaf/promise-utils'
 import ProjectAuditLogHandler from '../Project/ProjectAuditLogHandler.mjs'
 import ProjectAuditLogHandler from '../Project/ProjectAuditLogHandler.mjs'
 import Errors from '../Errors/Errors.js'
 import Errors from '../Errors/Errors.js'
 import AuthenticationController from '../Authentication/AuthenticationController.mjs'
 import AuthenticationController from '../Authentication/AuthenticationController.mjs'
-import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'
+import PrivilegeLevels from '../Authorization/PrivilegeLevels.mjs'
 
 
 // This rate limiter allows a different number of requests depending on the
 // This rate limiter allows a different number of requests depending on the
 // number of callaborators a user is allowed. This is implemented by providing
 // number of callaborators a user is allowed. This is implemented by providing

+ 1 - 1
services/web/app/src/Features/Collaborators/CollaboratorsInviteGetter.mjs

@@ -1,6 +1,6 @@
 import logger from '@overleaf/logger'
 import logger from '@overleaf/logger'
 import { ProjectInvite } from '../../models/ProjectInvite.mjs'
 import { ProjectInvite } from '../../models/ProjectInvite.mjs'
-import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'
+import PrivilegeLevels from '../Authorization/PrivilegeLevels.mjs'
 import CollaboratorsInviteHelper from './CollaboratorsInviteHelper.mjs'
 import CollaboratorsInviteHelper from './CollaboratorsInviteHelper.mjs'
 
 
 async function getAllInvites(projectId) {
 async function getAllInvites(projectId) {

+ 1 - 1
services/web/app/src/Features/Collaborators/CollaboratorsInviteHandler.mjs

@@ -8,7 +8,7 @@ import CollaboratorsInviteHelper from './CollaboratorsInviteHelper.mjs'
 import UserGetter from '../User/UserGetter.mjs'
 import UserGetter from '../User/UserGetter.mjs'
 import ProjectGetter from '../Project/ProjectGetter.mjs'
 import ProjectGetter from '../Project/ProjectGetter.mjs'
 import NotificationsBuilder from '../Notifications/NotificationsBuilder.mjs'
 import NotificationsBuilder from '../Notifications/NotificationsBuilder.mjs'
-import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'
+import PrivilegeLevels from '../Authorization/PrivilegeLevels.mjs'
 import LimitationsManager from '../Subscription/LimitationsManager.mjs'
 import LimitationsManager from '../Subscription/LimitationsManager.mjs'
 import ProjectAuditLogHandler from '../Project/ProjectAuditLogHandler.mjs'
 import ProjectAuditLogHandler from '../Project/ProjectAuditLogHandler.mjs'
 import _ from 'lodash'
 import _ from 'lodash'

+ 1 - 1
services/web/app/src/Features/Collaborators/OwnershipTransferHandler.mjs

@@ -5,7 +5,7 @@ import UserGetter from '../User/UserGetter.mjs'
 import CollaboratorsHandler from './CollaboratorsHandler.mjs'
 import CollaboratorsHandler from './CollaboratorsHandler.mjs'
 import EmailHandler from '../Email/EmailHandler.mjs'
 import EmailHandler from '../Email/EmailHandler.mjs'
 import Errors from '../Errors/Errors.js'
 import Errors from '../Errors/Errors.js'
-import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'
+import PrivilegeLevels from '../Authorization/PrivilegeLevels.mjs'
 import TpdsProjectFlusher from '../ThirdPartyDataStore/TpdsProjectFlusher.mjs'
 import TpdsProjectFlusher from '../ThirdPartyDataStore/TpdsProjectFlusher.mjs'
 import ProjectAuditLogHandler from '../Project/ProjectAuditLogHandler.mjs'
 import ProjectAuditLogHandler from '../Project/ProjectAuditLogHandler.mjs'
 import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
 import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'

+ 1 - 1
services/web/app/src/Features/Compile/ClsiCacheHandler.mjs

@@ -8,7 +8,7 @@ import logger from '@overleaf/logger'
 import Settings from '@overleaf/settings'
 import Settings from '@overleaf/settings'
 import OError from '@overleaf/o-error'
 import OError from '@overleaf/o-error'
 import { NotFoundError, InvalidNameError } from '../Errors/Errors.js'
 import { NotFoundError, InvalidNameError } from '../Errors/Errors.js'
-import Features from '../../infrastructure/Features.js'
+import Features from '../../infrastructure/Features.mjs'
 
 
 const TIMEOUT = 4_000
 const TIMEOUT = 4_000
 
 

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

@@ -7,7 +7,7 @@ import UserGetter from '../User/UserGetter.mjs'
 import Settings from '@overleaf/settings'
 import Settings from '@overleaf/settings'
 import { fetchJson, RequestFailedError } from '@overleaf/fetch-utils'
 import { fetchJson, RequestFailedError } from '@overleaf/fetch-utils'
 import Metrics from '@overleaf/metrics'
 import Metrics from '@overleaf/metrics'
-import Features from '../../infrastructure/Features.js'
+import Features from '../../infrastructure/Features.mjs'
 
 
 /**
 /**
  * Get the most recent build and metadata
  * Get the most recent build and metadata

+ 1 - 1
services/web/app/src/Features/Compile/CompileController.mjs

@@ -21,7 +21,7 @@ import {
   fetchStreamWithResponse,
   fetchStreamWithResponse,
   RequestFailedError,
   RequestFailedError,
 } from '@overleaf/fetch-utils'
 } from '@overleaf/fetch-utils'
-import Features from '../../infrastructure/Features.js'
+import Features from '../../infrastructure/Features.mjs'
 
 
 const { z, zz, validateReq } = Validation
 const { z, zz, validateReq } = Validation
 const ClsiCookieManager = ClsiCookieManagerFactory(
 const ClsiCookieManager = ClsiCookieManagerFactory(

+ 1 - 1
services/web/app/src/Features/Editor/EditorHttpController.mjs

@@ -5,7 +5,7 @@ import AuthorizationManager from '../Authorization/AuthorizationManager.mjs'
 import ProjectEditorHandler from '../Project/ProjectEditorHandler.mjs'
 import ProjectEditorHandler from '../Project/ProjectEditorHandler.mjs'
 import Metrics from '@overleaf/metrics'
 import Metrics from '@overleaf/metrics'
 import CollaboratorsInviteGetter from '../Collaborators/CollaboratorsInviteGetter.mjs'
 import CollaboratorsInviteGetter from '../Collaborators/CollaboratorsInviteGetter.mjs'
-import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'
+import PrivilegeLevels from '../Authorization/PrivilegeLevels.mjs'
 import SessionManager from '../Authentication/SessionManager.mjs'
 import SessionManager from '../Authentication/SessionManager.mjs'
 import Errors from '../Errors/Errors.js'
 import Errors from '../Errors/Errors.js'
 import { expressify } from '@overleaf/promise-utils'
 import { expressify } from '@overleaf/promise-utils'

+ 2 - 2
services/web/app/src/Features/Email/Bodies/NoCTAEmailBody.js → services/web/app/src/Features/Email/Bodies/NoCTAEmailBody.mjs

@@ -1,6 +1,6 @@
-const _ = require('lodash')
+import _ from 'lodash'
 
 
-module.exports = _.template(`\
+export default _.template(`\
 	<table class="row" style="border-collapse: collapse; border-spacing: 0; display: table; padding: 0; position: relative; text-align: left; vertical-align: top; width: 100%;">
 	<table class="row" style="border-collapse: collapse; border-spacing: 0; display: table; padding: 0; position: relative; text-align: left; vertical-align: top; width: 100%;">
 		<tbody>
 		<tbody>
 			<tr style="padding: 0; vertical-align: top;">
 			<tr style="padding: 0; vertical-align: top;">

+ 2 - 2
services/web/app/src/Features/Email/Bodies/cta-email.js → services/web/app/src/Features/Email/Bodies/cta-email.mjs

@@ -1,6 +1,6 @@
-const _ = require('lodash')
+import _ from 'lodash'
 
 
-module.exports = _.template(`\
+export default _.template(`\
 	<table class="row" style="border-collapse: collapse; border-spacing: 0; display: table; padding: 0; position: relative; text-align: left; vertical-align: top; width: 100%;">
 	<table class="row" style="border-collapse: collapse; border-spacing: 0; display: table; padding: 0; position: relative; text-align: left; vertical-align: top; width: 100%;">
 		<tbody>
 		<tbody>
 			<tr style="padding: 0; vertical-align: top;">
 			<tr style="padding: 0; vertical-align: top;">

+ 4 - 4
services/web/app/src/Features/Email/EmailBuilder.mjs

@@ -1,12 +1,12 @@
 import _ from 'lodash'
 import _ from 'lodash'
 import settings from '@overleaf/settings'
 import settings from '@overleaf/settings'
 import moment from 'moment'
 import moment from 'moment'
-import EmailMessageHelper from './EmailMessageHelper.js'
+import EmailMessageHelper from './EmailMessageHelper.mjs'
 import StringHelper from '../Helpers/StringHelper.mjs'
 import StringHelper from '../Helpers/StringHelper.mjs'
-import BaseWithHeaderEmailLayout from './Layouts/BaseWithHeaderEmailLayout.js'
+import BaseWithHeaderEmailLayout from './Layouts/BaseWithHeaderEmailLayout.mjs'
 import SpamSafe from './SpamSafe.mjs'
 import SpamSafe from './SpamSafe.mjs'
-import ctaEmailBody from './Bodies/cta-email.js'
-import NoCTAEmailBody from './Bodies/NoCTAEmailBody.js'
+import ctaEmailBody from './Bodies/cta-email.mjs'
+import NoCTAEmailBody from './Bodies/NoCTAEmailBody.mjs'
 
 
 function _emailBodyPlainText(content, opts, ctaEmail) {
 function _emailBodyPlainText(content, opts, ctaEmail) {
   let emailBody = `${content.greeting(opts, true)}`
   let emailBody = `${content.greeting(opts, true)}`

+ 1 - 1
services/web/app/src/Features/Email/EmailHandler.mjs

@@ -3,7 +3,7 @@ import Settings from '@overleaf/settings'
 import logger from '@overleaf/logger'
 import logger from '@overleaf/logger'
 import EmailBuilder from './EmailBuilder.mjs'
 import EmailBuilder from './EmailBuilder.mjs'
 import EmailSender from './EmailSender.mjs'
 import EmailSender from './EmailSender.mjs'
-import Queues from '../../infrastructure/Queues.js'
+import Queues from '../../infrastructure/Queues.mjs'
 
 
 const EMAIL_SETTINGS = Settings.email || {}
 const EMAIL_SETTINGS = Settings.email || {}
 
 

+ 2 - 2
services/web/app/src/Features/Email/EmailMessageHelper.js → services/web/app/src/Features/Email/EmailMessageHelper.mjs

@@ -1,4 +1,4 @@
-const sanitizeHtml = require('sanitize-html')
+import sanitizeHtml from 'sanitize-html'
 const sanitizeOptions = {
 const sanitizeOptions = {
   html: {
   html: {
     allowedTags: ['a', 'span', 'b', 'br', 'i'],
     allowedTags: ['a', 'span', 'b', 'br', 'i'],
@@ -22,7 +22,7 @@ function displayLink(text, url, isPlainText) {
   return isPlainText ? `${text} (${url})` : `<a href="${url}">${text}</a>`
   return isPlainText ? `${text} (${url})` : `<a href="${url}">${text}</a>`
 }
 }
 
 
-module.exports = {
+export default {
   cleanHTML,
   cleanHTML,
   displayLink,
   displayLink,
 }
 }

+ 3 - 3
services/web/app/src/Features/Email/Layouts/BaseWithHeaderEmailLayout.js → services/web/app/src/Features/Email/Layouts/BaseWithHeaderEmailLayout.mjs

@@ -1,7 +1,7 @@
-const _ = require('lodash')
-const settings = require('@overleaf/settings')
+import _ from 'lodash'
+import settings from '@overleaf/settings'
 
 
-module.exports = _.template(`\
+export default _.template(`\
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
 

+ 6 - 4
services/web/app/src/Features/Helpers/Mongo.js → services/web/app/src/Features/Helpers/Mongo.mjs

@@ -1,6 +1,8 @@
-const OError = require('@overleaf/o-error')
-const { ObjectId } = require('mongodb-legacy')
-const { ObjectId: MongooseObjectId } = require('mongoose').mongo
+import OError from '@overleaf/o-error'
+import mongodb from 'mongodb-legacy'
+import { ObjectId as MongooseObjectId } from 'mongoose'
+
+const { ObjectId } = mongodb
 
 
 function _getObjectIdInstance(id) {
 function _getObjectIdInstance(id) {
   if (typeof id === 'string') {
   if (typeof id === 'string') {
@@ -47,7 +49,7 @@ function isObjectIdInstance(id) {
   return id instanceof ObjectId || id instanceof MongooseObjectId
   return id instanceof ObjectId || id instanceof MongooseObjectId
 }
 }
 
 
-module.exports = {
+export default {
   isObjectIdInstance,
   isObjectIdInstance,
   normalizeQuery,
   normalizeQuery,
   normalizeMultiQuery,
   normalizeMultiQuery,

+ 1 - 1
services/web/app/src/Features/History/HistoryController.mjs

@@ -24,7 +24,7 @@ import ProjectDetailsHandler from '../Project/ProjectDetailsHandler.mjs'
 import ProjectEntityUpdateHandler from '../Project/ProjectEntityUpdateHandler.mjs'
 import ProjectEntityUpdateHandler from '../Project/ProjectEntityUpdateHandler.mjs'
 import RestoreManager from './RestoreManager.mjs'
 import RestoreManager from './RestoreManager.mjs'
 import { prepareZipAttachment } from '../../infrastructure/Response.js'
 import { prepareZipAttachment } from '../../infrastructure/Response.js'
-import Features from '../../infrastructure/Features.js'
+import Features from '../../infrastructure/Features.mjs'
 import { z, zz, validateReq } from '../../infrastructure/Validation.js'
 import { z, zz, validateReq } from '../../infrastructure/Validation.js'
 
 
 // Number of seconds after which the browser should send a request to revalidate
 // Number of seconds after which the browser should send a request to revalidate

+ 3 - 3
services/web/app/src/Features/Project/ProjectController.mjs

@@ -21,14 +21,14 @@ import AuthorizationManager from '../Authorization/AuthorizationManager.mjs'
 import InactiveProjectManager from '../InactiveData/InactiveProjectManager.mjs'
 import InactiveProjectManager from '../InactiveData/InactiveProjectManager.mjs'
 import ProjectUpdateHandler from './ProjectUpdateHandler.mjs'
 import ProjectUpdateHandler from './ProjectUpdateHandler.mjs'
 import ProjectGetter from './ProjectGetter.mjs'
 import ProjectGetter from './ProjectGetter.mjs'
-import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'
+import PrivilegeLevels from '../Authorization/PrivilegeLevels.mjs'
 import SessionManager from '../Authentication/SessionManager.mjs'
 import SessionManager from '../Authentication/SessionManager.mjs'
 import Sources from '../Authorization/Sources.mjs'
 import Sources from '../Authorization/Sources.mjs'
 import TokenAccessHandler from '../TokenAccess/TokenAccessHandler.mjs'
 import TokenAccessHandler from '../TokenAccess/TokenAccessHandler.mjs'
 import CollaboratorsGetter from '../Collaborators/CollaboratorsGetter.mjs'
 import CollaboratorsGetter from '../Collaborators/CollaboratorsGetter.mjs'
 import ProjectEntityHandler from './ProjectEntityHandler.mjs'
 import ProjectEntityHandler from './ProjectEntityHandler.mjs'
 import TpdsProjectFlusher from '../ThirdPartyDataStore/TpdsProjectFlusher.mjs'
 import TpdsProjectFlusher from '../ThirdPartyDataStore/TpdsProjectFlusher.mjs'
-import Features from '../../infrastructure/Features.js'
+import Features from '../../infrastructure/Features.mjs'
 import BrandVariationsHandler from '../BrandVariations/BrandVariationsHandler.mjs'
 import BrandVariationsHandler from '../BrandVariations/BrandVariationsHandler.mjs'
 import UserController from '../User/UserController.mjs'
 import UserController from '../User/UserController.mjs'
 import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
 import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
@@ -47,7 +47,7 @@ import UserUpdater from '../User/UserUpdater.mjs'
 import Modules from '../../infrastructure/Modules.js'
 import Modules from '../../infrastructure/Modules.js'
 import { z, zz, validateReq } from '../../infrastructure/Validation.js'
 import { z, zz, validateReq } from '../../infrastructure/Validation.js'
 import UserGetter from '../User/UserGetter.mjs'
 import UserGetter from '../User/UserGetter.mjs'
-import { isStandaloneAiAddOnPlanCode } from '../Subscription/AiHelper.js'
+import { isStandaloneAiAddOnPlanCode } from '../Subscription/AiHelper.mjs'
 import SubscriptionController from '../Subscription/SubscriptionController.mjs'
 import SubscriptionController from '../Subscription/SubscriptionController.mjs'
 import { formatCurrency } from '../../util/currency.js'
 import { formatCurrency } from '../../util/currency.js'
 import UserSettingsHelper from './UserSettingsHelper.mjs'
 import UserSettingsHelper from './UserSettingsHelper.mjs'

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

@@ -2,7 +2,7 @@ import OError from '@overleaf/o-error'
 import metrics from '@overleaf/metrics'
 import metrics from '@overleaf/metrics'
 import Settings from '@overleaf/settings'
 import Settings from '@overleaf/settings'
 import mongodb from 'mongodb-legacy'
 import mongodb from 'mongodb-legacy'
-import Features from '../../infrastructure/Features.js'
+import Features from '../../infrastructure/Features.mjs'
 import { Project } from '../../models/Project.mjs'
 import { Project } from '../../models/Project.mjs'
 import { Folder } from '../../models/Folder.mjs'
 import { Folder } from '../../models/Folder.mjs'
 import ProjectEntityUpdateHandler from './ProjectEntityUpdateHandler.mjs'
 import ProjectEntityUpdateHandler from './ProjectEntityUpdateHandler.mjs'

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

@@ -6,7 +6,7 @@ import logger from '@overleaf/logger'
 import TpdsUpdateSender from '../ThirdPartyDataStore/TpdsUpdateSender.mjs'
 import TpdsUpdateSender from '../ThirdPartyDataStore/TpdsUpdateSender.mjs'
 import PublicAccessLevels from '../Authorization/PublicAccessLevels.mjs'
 import PublicAccessLevels from '../Authorization/PublicAccessLevels.mjs'
 import Errors from '../Errors/Errors.js'
 import Errors from '../Errors/Errors.js'
-import TokenGenerator from '../TokenGenerator/TokenGenerator.js'
+import TokenGenerator from '../TokenGenerator/TokenGenerator.mjs'
 import ProjectHelper from './ProjectHelper.mjs'
 import ProjectHelper from './ProjectHelper.mjs'
 import settings from '@overleaf/settings'
 import settings from '@overleaf/settings'
 import { callbackify } from 'node:util'
 import { callbackify } from 'node:util'

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

@@ -1,5 +1,5 @@
 import { db } from '../../infrastructure/mongodb.js'
 import { db } from '../../infrastructure/mongodb.js'
-import { normalizeQuery } from '../Helpers/Mongo.js'
+import Mongo from '../Helpers/Mongo.mjs'
 import OError from '@overleaf/o-error'
 import OError from '@overleaf/o-error'
 import { Project } from '../../models/Project.mjs'
 import { Project } from '../../models/Project.mjs'
 import LockManager from '../../infrastructure/LockManager.js'
 import LockManager from '../../infrastructure/LockManager.js'
@@ -8,6 +8,8 @@ import { callbackifyAll } from '@overleaf/promise-utils'
 import ProjectEntityMongoUpdateHandler from './ProjectEntityMongoUpdateHandler.mjs'
 import ProjectEntityMongoUpdateHandler from './ProjectEntityMongoUpdateHandler.mjs'
 import CollaboratorsGetter from '../Collaborators/CollaboratorsGetter.mjs'
 import CollaboratorsGetter from '../Collaborators/CollaboratorsGetter.mjs'
 
 
+const { normalizeQuery } = Mongo
+
 const ProjectGetter = {
 const ProjectGetter = {
   EXCLUDE_DEPTH: 8,
   EXCLUDE_DEPTH: 8,
 
 

+ 2 - 2
services/web/app/src/Features/Project/ProjectListController.mjs

@@ -6,7 +6,7 @@ import Metrics from '@overleaf/metrics'
 import Settings from '@overleaf/settings'
 import Settings from '@overleaf/settings'
 import ProjectHelper from './ProjectHelper.mjs'
 import ProjectHelper from './ProjectHelper.mjs'
 import ProjectGetter from './ProjectGetter.mjs'
 import ProjectGetter from './ProjectGetter.mjs'
-import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'
+import PrivilegeLevels from '../Authorization/PrivilegeLevels.mjs'
 import SessionManager from '../Authentication/SessionManager.mjs'
 import SessionManager from '../Authentication/SessionManager.mjs'
 import Sources from '../Authorization/Sources.mjs'
 import Sources from '../Authorization/Sources.mjs'
 import UserGetter from '../User/UserGetter.mjs'
 import UserGetter from '../User/UserGetter.mjs'
@@ -14,7 +14,7 @@ import SurveyHandler from '../Survey/SurveyHandler.mjs'
 import TagsHandler from '../Tags/TagsHandler.mjs'
 import TagsHandler from '../Tags/TagsHandler.mjs'
 import { expressify } from '@overleaf/promise-utils'
 import { expressify } from '@overleaf/promise-utils'
 import logger from '@overleaf/logger'
 import logger from '@overleaf/logger'
-import Features from '../../infrastructure/Features.js'
+import Features from '../../infrastructure/Features.mjs'
 import SubscriptionViewModelBuilder from '../Subscription/SubscriptionViewModelBuilder.mjs'
 import SubscriptionViewModelBuilder from '../Subscription/SubscriptionViewModelBuilder.mjs'
 import NotificationsHandler from '../Notifications/NotificationsHandler.mjs'
 import NotificationsHandler from '../Notifications/NotificationsHandler.mjs'
 import Modules from '../../infrastructure/Modules.js'
 import Modules from '../../infrastructure/Modules.js'

+ 4 - 4
services/web/app/src/Features/Security/LoginRateLimiter.js → services/web/app/src/Features/Security/LoginRateLimiter.mjs

@@ -1,6 +1,6 @@
-const { RateLimiter } = require('../../infrastructure/RateLimiter')
-const { callbackify } = require('@overleaf/promise-utils')
-const Settings = require('@overleaf/settings')
+import { RateLimiter } from '../../infrastructure/RateLimiter.js'
+import { callbackify } from '@overleaf/promise-utils'
+import Settings from '@overleaf/settings'
 
 
 const rateLimiterLoginEmail = new RateLimiter(
 const rateLimiterLoginEmail = new RateLimiter(
   'login',
   'login',
@@ -38,4 +38,4 @@ LoginRateLimiter.promises = {
   recordSuccessfulLogin,
   recordSuccessfulLogin,
 }
 }
 
 
-module.exports = LoginRateLimiter
+export default LoginRateLimiter

+ 1 - 1
services/web/app/src/Features/Security/RateLimiterMiddleware.mjs

@@ -1,6 +1,6 @@
 import logger from '@overleaf/logger'
 import logger from '@overleaf/logger'
 import SessionManager from '../Authentication/SessionManager.mjs'
 import SessionManager from '../Authentication/SessionManager.mjs'
-import LoginRateLimiter from './LoginRateLimiter.js'
+import LoginRateLimiter from './LoginRateLimiter.mjs'
 import settings from '@overleaf/settings'
 import settings from '@overleaf/settings'
 
 
 /**
 /**

+ 1 - 1
services/web/app/src/Features/SplitTests/SplitTestHandler.mjs

@@ -8,7 +8,7 @@ import { callbackify } from 'node:util'
 import SplitTestCache from './SplitTestCache.mjs'
 import SplitTestCache from './SplitTestCache.mjs'
 import { SplitTest } from '../../models/SplitTest.mjs'
 import { SplitTest } from '../../models/SplitTest.mjs'
 import UserAnalyticsIdCache from '../Analytics/UserAnalyticsIdCache.mjs'
 import UserAnalyticsIdCache from '../Analytics/UserAnalyticsIdCache.mjs'
-import Features from '../../infrastructure/Features.js'
+import Features from '../../infrastructure/Features.mjs'
 import SplitTestUtils from './SplitTestUtils.mjs'
 import SplitTestUtils from './SplitTestUtils.mjs'
 import Settings from '@overleaf/settings'
 import Settings from '@overleaf/settings'
 import SessionManager from '../Authentication/SessionManager.mjs'
 import SessionManager from '../Authentication/SessionManager.mjs'

+ 1 - 1
services/web/app/src/Features/StaticPages/HomeController.mjs

@@ -1,4 +1,4 @@
-import Features from '../../infrastructure/Features.js'
+import Features from '../../infrastructure/Features.mjs'
 import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
 import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
 import Path from 'node:path'
 import Path from 'node:path'
 import fs from 'node:fs'
 import fs from 'node:fs'

+ 6 - 6
services/web/app/src/Features/Subscription/AiHelper.js → services/web/app/src/Features/Subscription/AiHelper.mjs

@@ -2,9 +2,9 @@
 // Initially, this functions lived in PaymentProviderEntities.js,
 // Initially, this functions lived in PaymentProviderEntities.js,
 // but it was moved to this file to prevent circular dependency issue
 // but it was moved to this file to prevent circular dependency issue
 
 
-const AI_ASSIST_STANDALONE_MONTHLY_PLAN_CODE = 'assistant'
-const AI_ASSIST_STANDALONE_ANNUAL_PLAN_CODE = 'assistant-annual'
-const AI_ADD_ON_CODE = 'assistant'
+export const AI_ASSIST_STANDALONE_MONTHLY_PLAN_CODE = 'assistant'
+export const AI_ASSIST_STANDALONE_ANNUAL_PLAN_CODE = 'assistant-annual'
+export const AI_ADD_ON_CODE = 'assistant'
 
 
 /**
 /**
  * Returns whether the given plan code is a standalone AI plan
  * Returns whether the given plan code is a standalone AI plan
@@ -12,7 +12,7 @@ const AI_ADD_ON_CODE = 'assistant'
  * @param {string | null | undefined} planCode
  * @param {string | null | undefined} planCode
  * @return {boolean}
  * @return {boolean}
  */
  */
-function isStandaloneAiAddOnPlanCode(planCode) {
+export function isStandaloneAiAddOnPlanCode(planCode) {
   return (
   return (
     planCode === AI_ASSIST_STANDALONE_MONTHLY_PLAN_CODE ||
     planCode === AI_ASSIST_STANDALONE_MONTHLY_PLAN_CODE ||
     planCode === AI_ASSIST_STANDALONE_ANNUAL_PLAN_CODE
     planCode === AI_ASSIST_STANDALONE_ANNUAL_PLAN_CODE
@@ -28,7 +28,7 @@ function isStandaloneAiAddOnPlanCode(planCode) {
  *
  *
  * @return {boolean}
  * @return {boolean}
  */
  */
-function subscriptionChangeIsAiAssistUpgrade(subscriptionChange) {
+export function subscriptionChangeIsAiAssistUpgrade(subscriptionChange) {
   return Boolean(
   return Boolean(
     isStandaloneAiAddOnPlanCode(subscriptionChange.nextPlanCode) ||
     isStandaloneAiAddOnPlanCode(subscriptionChange.nextPlanCode) ||
       subscriptionChange.nextAddOns?.some(
       subscriptionChange.nextAddOns?.some(
@@ -37,7 +37,7 @@ function subscriptionChangeIsAiAssistUpgrade(subscriptionChange) {
   )
   )
 }
 }
 
 
-module.exports = {
+export default {
   AI_ADD_ON_CODE,
   AI_ADD_ON_CODE,
   AI_ASSIST_STANDALONE_MONTHLY_PLAN_CODE,
   AI_ASSIST_STANDALONE_MONTHLY_PLAN_CODE,
   AI_ASSIST_STANDALONE_ANNUAL_PLAN_CODE,
   AI_ASSIST_STANDALONE_ANNUAL_PLAN_CODE,

+ 18 - 17
services/web/app/src/Features/Subscription/Errors.js → services/web/app/src/Features/Subscription/Errors.mjs

@@ -1,9 +1,10 @@
 // @ts-check
 // @ts-check
 
 
-const Errors = require('../Errors/Errors')
-const OError = require('@overleaf/o-error')
+import Errors from '../Errors/Errors.js'
 
 
-class RecurlyTransactionError extends Errors.BackwardCompatibleError {
+import OError from '@overleaf/o-error'
+
+export class RecurlyTransactionError extends Errors.BackwardCompatibleError {
   constructor(options) {
   constructor(options) {
     super({
     super({
       message: 'Unknown transaction error',
       message: 'Unknown transaction error',
@@ -12,27 +13,27 @@ class RecurlyTransactionError extends Errors.BackwardCompatibleError {
   }
   }
 }
 }
 
 
-class DuplicateAddOnError extends OError {}
+export class DuplicateAddOnError extends OError {}
 
 
-class AddOnNotPresentError extends OError {}
+export class AddOnNotPresentError extends OError {}
 
 
-class MissingBillingInfoError extends OError {}
+export class MissingBillingInfoError extends OError {}
 
 
-class ManuallyCollectedError extends OError {}
+export class ManuallyCollectedError extends OError {}
 
 
-class PendingChangeError extends OError {}
+export class PendingChangeError extends OError {}
 
 
-class InactiveError extends OError {}
+export class InactiveError extends OError {}
 
 
-class SubtotalLimitExceededError extends OError {}
+export class SubtotalLimitExceededError extends OError {}
 
 
-class HasPastDueInvoiceError extends OError {}
+export class HasPastDueInvoiceError extends OError {}
 
 
-class HasNoAdditionalLicenseWhenManuallyCollectedError extends OError {}
+export class HasNoAdditionalLicenseWhenManuallyCollectedError extends OError {}
 
 
-class InvalidTaxIdError extends OError {}
+export class InvalidTaxIdError extends OError {}
 
 
-class StripeClientIdempotencyKeyInUseError extends OError {
+export class StripeClientIdempotencyKeyInUseError extends OError {
   constructor() {
   constructor() {
     super('Stripe idempotency key was already in use')
     super('Stripe idempotency key was already in use')
   }
   }
@@ -43,7 +44,7 @@ class StripeClientIdempotencyKeyInUseError extends OError {
  * @property {string} PaymentActionRequiredInfo.clientSecret
  * @property {string} PaymentActionRequiredInfo.clientSecret
  * @property {string} PaymentActionRequiredInfo.publicKey
  * @property {string} PaymentActionRequiredInfo.publicKey
  */
  */
-class PaymentActionRequiredError extends OError {
+export class PaymentActionRequiredError extends OError {
   /**
   /**
    * @param {PaymentActionRequiredInfo} info
    * @param {PaymentActionRequiredInfo} info
    */
    */
@@ -58,7 +59,7 @@ class PaymentActionRequiredError extends OError {
  * @property {string} PaymentFailedInfo.reason
  * @property {string} PaymentFailedInfo.reason
  * @property {string} PaymentFailedInfo.adviceCode
  * @property {string} PaymentFailedInfo.adviceCode
  */
  */
-class PaymentFailedError extends OError {
+export class PaymentFailedError extends OError {
   /**
   /**
    * @param {PaymentFailedInfo} info
    * @param {PaymentFailedInfo} info
    */
    */
@@ -67,7 +68,7 @@ class PaymentFailedError extends OError {
   }
   }
 }
 }
 
 
-module.exports = {
+export default {
   RecurlyTransactionError,
   RecurlyTransactionError,
   DuplicateAddOnError,
   DuplicateAddOnError,
   AddOnNotPresentError,
   AddOnNotPresentError,

+ 2 - 2
services/web/app/src/Features/Subscription/FeaturesUpdater.mjs

@@ -13,9 +13,9 @@ import V1SubscriptionManager from './V1SubscriptionManager.mjs'
 import InstitutionsFeatures from '../Institutions/InstitutionsFeatures.mjs'
 import InstitutionsFeatures from '../Institutions/InstitutionsFeatures.mjs'
 import UserGetter from '../User/UserGetter.mjs'
 import UserGetter from '../User/UserGetter.mjs'
 import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
 import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
-import Queues from '../../infrastructure/Queues.js'
+import Queues from '../../infrastructure/Queues.mjs'
 import Modules from '../../infrastructure/Modules.js'
 import Modules from '../../infrastructure/Modules.js'
-import { AI_ADD_ON_CODE } from './AiHelper.js'
+import { AI_ADD_ON_CODE } from './AiHelper.mjs'
 
 
 /**
 /**
  * Enqueue a job for refreshing features for the given user
  * Enqueue a job for refreshing features for the given user

+ 5 - 5
services/web/app/src/Features/Subscription/GroupPlansData.js → services/web/app/src/Features/Subscription/GroupPlansData.mjs

@@ -1,6 +1,6 @@
-const Settings = require('@overleaf/settings')
-const fs = require('fs')
-const Path = require('path')
+import Settings from '@overleaf/settings'
+import fs from 'node:fs'
+import Path from 'node:path'
 
 
 // The groups.json file encodes the various group plan options we provide, and
 // The groups.json file encodes the various group plan options we provide, and
 // is used in the app the render the appropriate dialog in the plans page, and
 // is used in the app the render the appropriate dialog in the plans page, and
@@ -12,7 +12,7 @@ const Path = require('path')
 // fetch pricing data and generate a groups.json using the current Recurly
 // fetch pricing data and generate a groups.json using the current Recurly
 // prices
 // prices
 const data = fs.readFileSync(
 const data = fs.readFileSync(
-  Path.join(__dirname, '/../../../templates/plans/groups.json')
+  Path.join(import.meta.dirname, '/../../../templates/plans/groups.json')
 )
 )
 const groups = JSON.parse(data.toString())
 const groups = JSON.parse(data.toString())
 
 
@@ -63,4 +63,4 @@ for (const [usage, planData] of Object.entries(groups)) {
   }
   }
 }
 }
 
 
-module.exports = groups
+export default groups

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

@@ -8,7 +8,7 @@ import SubscriptionLocator from './SubscriptionLocator.mjs'
 import Settings from '@overleaf/settings'
 import Settings from '@overleaf/settings'
 import CollaboratorsGetter from '../Collaborators/CollaboratorsGetter.mjs'
 import CollaboratorsGetter from '../Collaborators/CollaboratorsGetter.mjs'
 import CollaboratorsInvitesGetter from '../Collaborators/CollaboratorsInviteGetter.mjs'
 import CollaboratorsInvitesGetter from '../Collaborators/CollaboratorsInviteGetter.mjs'
-import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'
+import PrivilegeLevels from '../Authorization/PrivilegeLevels.mjs'
 import { callbackify, callbackifyMultiResult } from '@overleaf/promise-utils'
 import { callbackify, callbackifyMultiResult } from '@overleaf/promise-utils'
 
 
 async function allowedNumberOfCollaboratorsInProject(projectId) {
 async function allowedNumberOfCollaboratorsInProject(projectId) {

+ 2 - 2
services/web/app/src/Features/Subscription/PaymentProviderEntities.mjs

@@ -18,10 +18,10 @@
 
 
 import OError from '@overleaf/o-error'
 import OError from '@overleaf/o-error'
 
 
-import { DuplicateAddOnError, AddOnNotPresentError } from './Errors.js'
+import { DuplicateAddOnError, AddOnNotPresentError } from './Errors.mjs'
 import PlansLocator from './PlansLocator.mjs'
 import PlansLocator from './PlansLocator.mjs'
 import SubscriptionHelper from './SubscriptionHelper.mjs'
 import SubscriptionHelper from './SubscriptionHelper.mjs'
-import { AI_ADD_ON_CODE, isStandaloneAiAddOnPlanCode } from './AiHelper.js'
+import { AI_ADD_ON_CODE, isStandaloneAiAddOnPlanCode } from './AiHelper.mjs'
 export const MEMBERS_LIMIT_ADD_ON_CODE = 'additional-license'
 export const MEMBERS_LIMIT_ADD_ON_CODE = 'additional-license'
 
 
 export class PaymentProviderSubscription {
 export class PaymentProviderSubscription {

+ 2 - 2
services/web/app/src/Features/Subscription/RecurlyClient.mjs

@@ -22,9 +22,9 @@ import {
 import {
 import {
   MissingBillingInfoError,
   MissingBillingInfoError,
   SubtotalLimitExceededError,
   SubtotalLimitExceededError,
-} from './Errors.js'
+} from './Errors.mjs'
 import RecurlyMetrics from './RecurlyMetrics.mjs'
 import RecurlyMetrics from './RecurlyMetrics.mjs'
-import { isStandaloneAiAddOnPlanCode, AI_ADD_ON_CODE } from './AiHelper.js'
+import { isStandaloneAiAddOnPlanCode, AI_ADD_ON_CODE } from './AiHelper.mjs'
 
 
 /**
 /**
  * @import { PaymentProviderSubscriptionChangeRequest } from './PaymentProviderEntities.mjs'
  * @import { PaymentProviderSubscriptionChangeRequest } from './PaymentProviderEntities.mjs'

+ 1 - 1
services/web/app/src/Features/Subscription/RecurlyEventHandler.mjs

@@ -1,7 +1,7 @@
 import SplitTestHandler from '../SplitTests/SplitTestHandler.mjs'
 import SplitTestHandler from '../SplitTests/SplitTestHandler.mjs'
 import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
 import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
 import SubscriptionEmailHandler from './SubscriptionEmailHandler.mjs'
 import SubscriptionEmailHandler from './SubscriptionEmailHandler.mjs'
-import { AI_ADD_ON_CODE } from './AiHelper.js'
+import { AI_ADD_ON_CODE } from './AiHelper.mjs'
 import mongodb from 'mongodb-legacy'
 import mongodb from 'mongodb-legacy'
 
 
 const { ObjectId } = mongodb
 const { ObjectId } = mongodb

+ 1 - 1
services/web/app/src/Features/Subscription/RecurlyWrapper.mjs

@@ -7,7 +7,7 @@ import Settings from '@overleaf/settings'
 import xml2js from 'xml2js'
 import xml2js from 'xml2js'
 import logger from '@overleaf/logger'
 import logger from '@overleaf/logger'
 import Errors from '../Errors/Errors.js'
 import Errors from '../Errors/Errors.js'
-import SubscriptionErrors from './Errors.js'
+import SubscriptionErrors from './Errors.mjs'
 import { callbackify } from '@overleaf/promise-utils'
 import { callbackify } from '@overleaf/promise-utils'
 import RecurlyMetrics from './RecurlyMetrics.mjs'
 import RecurlyMetrics from './RecurlyMetrics.mjs'
 
 

+ 3 - 3
services/web/app/src/Features/Subscription/SubscriptionController.mjs

@@ -10,13 +10,13 @@ import Settings from '@overleaf/settings'
 import logger from '@overleaf/logger'
 import logger from '@overleaf/logger'
 import GeoIpLookup from '../../infrastructure/GeoIpLookup.mjs'
 import GeoIpLookup from '../../infrastructure/GeoIpLookup.mjs'
 import FeaturesUpdater from './FeaturesUpdater.mjs'
 import FeaturesUpdater from './FeaturesUpdater.mjs'
-import GroupPlansData from './GroupPlansData.js'
+import GroupPlansData from './GroupPlansData.mjs'
 import V1SubscriptionManager from './V1SubscriptionManager.mjs'
 import V1SubscriptionManager from './V1SubscriptionManager.mjs'
 import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
 import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
 import RecurlyEventHandler from './RecurlyEventHandler.mjs'
 import RecurlyEventHandler from './RecurlyEventHandler.mjs'
 import { expressify } from '@overleaf/promise-utils'
 import { expressify } from '@overleaf/promise-utils'
 import OError from '@overleaf/o-error'
 import OError from '@overleaf/o-error'
-import Errors from './Errors.js'
+import Errors from './Errors.mjs'
 import SplitTestHandler from '../SplitTests/SplitTestHandler.mjs'
 import SplitTestHandler from '../SplitTests/SplitTestHandler.mjs'
 import AuthorizationManager from '../Authorization/AuthorizationManager.mjs'
 import AuthorizationManager from '../Authorization/AuthorizationManager.mjs'
 import Modules from '../../infrastructure/Modules.js'
 import Modules from '../../infrastructure/Modules.js'
@@ -26,7 +26,7 @@ import RecurlyClient from './RecurlyClient.mjs'
 import {
 import {
   AI_ADD_ON_CODE,
   AI_ADD_ON_CODE,
   subscriptionChangeIsAiAssistUpgrade,
   subscriptionChangeIsAiAssistUpgrade,
-} from './AiHelper.js'
+} from './AiHelper.mjs'
 import PlansLocator from './PlansLocator.mjs'
 import PlansLocator from './PlansLocator.mjs'
 import { User } from '../../models/User.mjs'
 import { User } from '../../models/User.mjs'
 import UserGetter from '../User/UserGetter.mjs'
 import UserGetter from '../User/UserGetter.mjs'

+ 1 - 1
services/web/app/src/Features/Subscription/SubscriptionEmailBuilder.mjs

@@ -1,5 +1,5 @@
 import EmailBuilder from '../Email/EmailBuilder.mjs'
 import EmailBuilder from '../Email/EmailBuilder.mjs'
-import EmailMessageHelper from '../Email/EmailMessageHelper.js'
+import EmailMessageHelper from '../Email/EmailMessageHelper.mjs'
 import settings from '@overleaf/settings'
 import settings from '@overleaf/settings'
 
 
 EmailBuilder.templates.trialOnboarding = EmailBuilder.NoCTAEmailTemplate({
 EmailBuilder.templates.trialOnboarding = EmailBuilder.NoCTAEmailTemplate({

+ 1 - 1
services/web/app/src/Features/Subscription/SubscriptionGroupController.mjs

@@ -20,7 +20,7 @@ import {
   HasPastDueInvoiceError,
   HasPastDueInvoiceError,
   HasNoAdditionalLicenseWhenManuallyCollectedError,
   HasNoAdditionalLicenseWhenManuallyCollectedError,
   PaymentActionRequiredError,
   PaymentActionRequiredError,
-} from './Errors.js'
+} from './Errors.mjs'
 
 
 const MAX_NUMBER_OF_USERS = 20
 const MAX_NUMBER_OF_USERS = 20
 const MAX_NUMBER_OF_PO_NUMBER_CHARACTERS = 50
 const MAX_NUMBER_OF_PO_NUMBER_CHARACTERS = 50

+ 2 - 2
services/web/app/src/Features/Subscription/SubscriptionGroupHandler.mjs

@@ -9,7 +9,7 @@ import { Subscription } from '../../models/Subscription.mjs'
 import { User } from '../../models/User.mjs'
 import { User } from '../../models/User.mjs'
 import PlansLocator from './PlansLocator.mjs'
 import PlansLocator from './PlansLocator.mjs'
 import TeamInvitesHandler from './TeamInvitesHandler.mjs'
 import TeamInvitesHandler from './TeamInvitesHandler.mjs'
-import GroupPlansData from './GroupPlansData.js'
+import GroupPlansData from './GroupPlansData.mjs'
 import Modules from '../../infrastructure/Modules.js'
 import Modules from '../../infrastructure/Modules.js'
 import PaymentProviderEntities from './PaymentProviderEntities.mjs'
 import PaymentProviderEntities from './PaymentProviderEntities.mjs'
 import {
 import {
@@ -18,7 +18,7 @@ import {
   InactiveError,
   InactiveError,
   HasPastDueInvoiceError,
   HasPastDueInvoiceError,
   HasNoAdditionalLicenseWhenManuallyCollectedError,
   HasNoAdditionalLicenseWhenManuallyCollectedError,
-} from './Errors.js'
+} from './Errors.mjs'
 import EmailHelper from '../Helpers/EmailHelper.mjs'
 import EmailHelper from '../Helpers/EmailHelper.mjs'
 import { InvalidEmailError } from '../Errors/Errors.js'
 import { InvalidEmailError } from '../Errors/Errors.js'
 
 

+ 2 - 2
services/web/app/src/Features/Subscription/SubscriptionHelper.mjs

@@ -2,8 +2,8 @@
 
 
 import Settings from '@overleaf/settings'
 import Settings from '@overleaf/settings'
 import { formatCurrency } from '../../util/currency.js'
 import { formatCurrency } from '../../util/currency.js'
-import GroupPlansData from './GroupPlansData.js'
-import { isStandaloneAiAddOnPlanCode } from './AiHelper.js'
+import GroupPlansData from './GroupPlansData.mjs'
+import { isStandaloneAiAddOnPlanCode } from './AiHelper.mjs'
 import { Subscription } from '../../models/Subscription.mjs'
 import { Subscription } from '../../models/Subscription.mjs'
 
 
 const MILLISECONDS = 1_000
 const MILLISECONDS = 1_000

+ 2 - 2
services/web/app/src/Features/Subscription/SubscriptionLocator.mjs

@@ -8,8 +8,8 @@ import { Subscription } from '../../models/Subscription.mjs'
 import SubscriptionHelper from './SubscriptionHelper.mjs'
 import SubscriptionHelper from './SubscriptionHelper.mjs'
 import { DeletedSubscription } from '../../models/DeletedSubscription.mjs'
 import { DeletedSubscription } from '../../models/DeletedSubscription.mjs'
 import logger from '@overleaf/logger'
 import logger from '@overleaf/logger'
-import { AI_ADD_ON_CODE, isStandaloneAiAddOnPlanCode } from './AiHelper.js'
-import './GroupPlansData.js' // make sure dynamic group plans are loaded
+import { AI_ADD_ON_CODE, isStandaloneAiAddOnPlanCode } from './AiHelper.mjs'
+import './GroupPlansData.mjs' // make sure dynamic group plans are loaded
 
 
 const SubscriptionLocator = {
 const SubscriptionLocator = {
   async getUsersSubscription(userOrId) {
   async getUsersSubscription(userOrId) {

+ 1 - 1
services/web/app/src/Features/Subscription/SubscriptionUpdater.mjs

@@ -8,7 +8,7 @@ import FeaturesHelper from './FeaturesHelper.mjs'
 import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
 import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
 import { DeletedSubscription } from '../../models/DeletedSubscription.mjs'
 import { DeletedSubscription } from '../../models/DeletedSubscription.mjs'
 import logger from '@overleaf/logger'
 import logger from '@overleaf/logger'
-import Features from '../../infrastructure/Features.js'
+import Features from '../../infrastructure/Features.mjs'
 import UserAuditLogHandler from '../User/UserAuditLogHandler.mjs'
 import UserAuditLogHandler from '../User/UserAuditLogHandler.mjs'
 import UserUpdater from '../User/UserUpdater.mjs'
 import UserUpdater from '../User/UserUpdater.mjs'
 import AccountMappingHelper from '../Analytics/AccountMappingHelper.mjs'
 import AccountMappingHelper from '../Analytics/AccountMappingHelper.mjs'

+ 1 - 1
services/web/app/src/Features/Subscription/SubscriptionViewModelBuilder.mjs

@@ -2,7 +2,7 @@
 import Settings from '@overleaf/settings'
 import Settings from '@overleaf/settings'
 
 
 import PlansLocator from './PlansLocator.mjs'
 import PlansLocator from './PlansLocator.mjs'
-import { isStandaloneAiAddOnPlanCode } from './AiHelper.js'
+import { isStandaloneAiAddOnPlanCode } from './AiHelper.mjs'
 import PaymentProviderEntities from './PaymentProviderEntities.mjs'
 import PaymentProviderEntities from './PaymentProviderEntities.mjs'
 import SubscriptionFormatters from './SubscriptionFormatters.mjs'
 import SubscriptionFormatters from './SubscriptionFormatters.mjs'
 import SubscriptionLocator from './SubscriptionLocator.mjs'
 import SubscriptionLocator from './SubscriptionLocator.mjs'

+ 1 - 1
services/web/app/src/Features/TokenAccess/TokenAccessController.mjs

@@ -6,7 +6,7 @@ import logger from '@overleaf/logger'
 import OError from '@overleaf/o-error'
 import OError from '@overleaf/o-error'
 import { expressify } from '@overleaf/promise-utils'
 import { expressify } from '@overleaf/promise-utils'
 import AuthorizationManager from '../Authorization/AuthorizationManager.mjs'
 import AuthorizationManager from '../Authorization/AuthorizationManager.mjs'
-import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'
+import PrivilegeLevels from '../Authorization/PrivilegeLevels.mjs'
 import ProjectAuditLogHandler from '../Project/ProjectAuditLogHandler.mjs'
 import ProjectAuditLogHandler from '../Project/ProjectAuditLogHandler.mjs'
 import CollaboratorsInviteHandler from '../Collaborators/CollaboratorsInviteHandler.mjs'
 import CollaboratorsInviteHandler from '../Collaborators/CollaboratorsInviteHandler.mjs'
 import CollaboratorsHandler from '../Collaborators/CollaboratorsHandler.mjs'
 import CollaboratorsHandler from '../Collaborators/CollaboratorsHandler.mjs'

+ 3 - 3
services/web/app/src/Features/TokenAccess/TokenAccessHandler.mjs

@@ -1,15 +1,15 @@
 import { Project } from '../../models/Project.mjs'
 import { Project } from '../../models/Project.mjs'
 import PublicAccessLevels from '../Authorization/PublicAccessLevels.mjs'
 import PublicAccessLevels from '../Authorization/PublicAccessLevels.mjs'
-import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'
+import PrivilegeLevels from '../Authorization/PrivilegeLevels.mjs'
 import mongodb from 'mongodb-legacy'
 import mongodb from 'mongodb-legacy'
 import Metrics from '@overleaf/metrics'
 import Metrics from '@overleaf/metrics'
 import Settings from '@overleaf/settings'
 import Settings from '@overleaf/settings'
 import logger from '@overleaf/logger'
 import logger from '@overleaf/logger'
-import V1Api from '../V1/V1Api.js'
+import V1Api from '../V1/V1Api.mjs'
 import crypto from 'node:crypto'
 import crypto from 'node:crypto'
 import { callbackifyAll } from '@overleaf/promise-utils'
 import { callbackifyAll } from '@overleaf/promise-utils'
 import Analytics from '../Analytics/AnalyticsManager.mjs'
 import Analytics from '../Analytics/AnalyticsManager.mjs'
-import Features from '../../infrastructure/Features.js'
+import Features from '../../infrastructure/Features.mjs'
 
 
 const { ObjectId } = mongodb
 const { ObjectId } = mongodb
 
 

+ 5 - 5
services/web/app/src/Features/TokenGenerator/TokenGenerator.js → services/web/app/src/Features/TokenGenerator/TokenGenerator.mjs

@@ -1,7 +1,7 @@
-const crypto = require('crypto')
-const V1Api = require('../V1/V1Api')
-const Features = require('../../infrastructure/Features')
-const { callbackify } = require('util')
+import crypto from 'node:crypto'
+import V1Api from '../V1/V1Api.mjs'
+import Features from '../../infrastructure/Features.mjs'
+import { callbackify } from 'node:util'
 
 
 // (From Overleaf `random_token.rb`)
 // (From Overleaf `random_token.rb`)
 //   Letters (not numbers! see generate_token) used in tokens. They're all
 //   Letters (not numbers! see generate_token) used in tokens. They're all
@@ -94,4 +94,4 @@ const TokenGenerator = {
 TokenGenerator.promises = {
 TokenGenerator.promises = {
   generateUniqueReadOnlyToken,
   generateUniqueReadOnlyToken,
 }
 }
-module.exports = TokenGenerator
+export default TokenGenerator

+ 5 - 5
services/web/app/src/Features/Uploads/ArchiveErrors.js → services/web/app/src/Features/Uploads/ArchiveErrors.mjs

@@ -1,6 +1,6 @@
-const Errors = require('../Errors/Errors')
+import Errors from '../Errors/Errors.js'
 
 
-class InvalidZipFileError extends Errors.BackwardCompatibleError {
+export class InvalidZipFileError extends Errors.BackwardCompatibleError {
   constructor(options) {
   constructor(options) {
     super({
     super({
       message: 'invalid_zip_file',
       message: 'invalid_zip_file',
@@ -9,7 +9,7 @@ class InvalidZipFileError extends Errors.BackwardCompatibleError {
   }
   }
 }
 }
 
 
-class EmptyZipFileError extends InvalidZipFileError {
+export class EmptyZipFileError extends InvalidZipFileError {
   constructor(options) {
   constructor(options) {
     super({
     super({
       message: 'empty_zip_file',
       message: 'empty_zip_file',
@@ -18,7 +18,7 @@ class EmptyZipFileError extends InvalidZipFileError {
   }
   }
 }
 }
 
 
-class ZipContentsTooLargeError extends InvalidZipFileError {
+export class ZipContentsTooLargeError extends InvalidZipFileError {
   constructor(options) {
   constructor(options) {
     super({
     super({
       message: 'zip_contents_too_large',
       message: 'zip_contents_too_large',
@@ -27,7 +27,7 @@ class ZipContentsTooLargeError extends InvalidZipFileError {
   }
   }
 }
 }
 
 
-module.exports = {
+export default {
   InvalidZipFileError,
   InvalidZipFileError,
   EmptyZipFileError,
   EmptyZipFileError,
   ZipContentsTooLargeError,
   ZipContentsTooLargeError,

+ 1 - 1
services/web/app/src/Features/Uploads/ArchiveManager.mjs

@@ -24,7 +24,7 @@ import {
   InvalidZipFileError,
   InvalidZipFileError,
   EmptyZipFileError,
   EmptyZipFileError,
   ZipContentsTooLargeError,
   ZipContentsTooLargeError,
-} from './ArchiveErrors.js'
+} from './ArchiveErrors.mjs'
 import _ from 'lodash'
 import _ from 'lodash'
 import { promisifyAll } from '@overleaf/promise-utils'
 import { promisifyAll } from '@overleaf/promise-utils'
 
 

+ 1 - 1
services/web/app/src/Features/Uploads/ProjectUploadController.mjs

@@ -8,7 +8,7 @@ import SessionManager from '../Authentication/SessionManager.mjs'
 import EditorController from '../Editor/EditorController.mjs'
 import EditorController from '../Editor/EditorController.mjs'
 import ProjectLocator from '../Project/ProjectLocator.mjs'
 import ProjectLocator from '../Project/ProjectLocator.mjs'
 import Settings from '@overleaf/settings'
 import Settings from '@overleaf/settings'
-import { InvalidZipFileError } from './ArchiveErrors.js'
+import { InvalidZipFileError } from './ArchiveErrors.mjs'
 import multer from 'multer'
 import multer from 'multer'
 import lodash from 'lodash'
 import lodash from 'lodash'
 import { expressify } from '@overleaf/promise-utils'
 import { expressify } from '@overleaf/promise-utils'

+ 1 - 1
services/web/app/src/Features/User/UserController.mjs

@@ -7,7 +7,7 @@ import logger from '@overleaf/logger'
 import metrics from '@overleaf/metrics'
 import metrics from '@overleaf/metrics'
 import AuthenticationManager from '../Authentication/AuthenticationManager.mjs'
 import AuthenticationManager from '../Authentication/AuthenticationManager.mjs'
 import SessionManager from '../Authentication/SessionManager.mjs'
 import SessionManager from '../Authentication/SessionManager.mjs'
-import Features from '../../infrastructure/Features.js'
+import Features from '../../infrastructure/Features.mjs'
 import { z, validateReq } from '../../infrastructure/Validation.js'
 import { z, validateReq } from '../../infrastructure/Validation.js'
 import UserAuditLogHandler from './UserAuditLogHandler.mjs'
 import UserAuditLogHandler from './UserAuditLogHandler.mjs'
 import UserSessionsManager from './UserSessionsManager.mjs'
 import UserSessionsManager from './UserSessionsManager.mjs'

+ 1 - 1
services/web/app/src/Features/User/UserCreator.mjs

@@ -1,7 +1,7 @@
 import logger from '@overleaf/logger'
 import logger from '@overleaf/logger'
 import util from 'node:util'
 import util from 'node:util'
 import { AffiliationError } from '../Errors/Errors.js'
 import { AffiliationError } from '../Errors/Errors.js'
-import Features from '../../infrastructure/Features.js'
+import Features from '../../infrastructure/Features.mjs'
 import { User } from '../../models/User.mjs'
 import { User } from '../../models/User.mjs'
 import UserDeleter from './UserDeleter.mjs'
 import UserDeleter from './UserDeleter.mjs'
 import UserGetter from './UserGetter.mjs'
 import UserGetter from './UserGetter.mjs'

+ 1 - 1
services/web/app/src/Features/User/UserEmailsController.mjs

@@ -17,7 +17,7 @@ import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
 import UserPrimaryEmailCheckHandler from '../User/UserPrimaryEmailCheckHandler.mjs'
 import UserPrimaryEmailCheckHandler from '../User/UserPrimaryEmailCheckHandler.mjs'
 import UserAuditLogHandler from './UserAuditLogHandler.mjs'
 import UserAuditLogHandler from './UserAuditLogHandler.mjs'
 import { RateLimiter } from '../../infrastructure/RateLimiter.js'
 import { RateLimiter } from '../../infrastructure/RateLimiter.js'
-import Features from '../../infrastructure/Features.js'
+import Features from '../../infrastructure/Features.mjs'
 import tsscmp from 'tsscmp'
 import tsscmp from 'tsscmp'
 import Modules from '../../infrastructure/Modules.js'
 import Modules from '../../infrastructure/Modules.js'
 
 

+ 3 - 2
services/web/app/src/Features/User/UserGetter.mjs

@@ -5,13 +5,14 @@ import settings from '@overleaf/settings'
 import InstitutionsAPI from '../Institutions/InstitutionsAPI.mjs'
 import InstitutionsAPI from '../Institutions/InstitutionsAPI.mjs'
 import InstitutionsHelper from '../Institutions/InstitutionsHelper.mjs'
 import InstitutionsHelper from '../Institutions/InstitutionsHelper.mjs'
 import Errors from '../Errors/Errors.js'
 import Errors from '../Errors/Errors.js'
-import Features from '../../infrastructure/Features.js'
+import Features from '../../infrastructure/Features.mjs'
 import { User } from '../../models/User.mjs'
 import { User } from '../../models/User.mjs'
-import { normalizeQuery, normalizeMultiQuery } from '../Helpers/Mongo.js'
+import Mongo from '../Helpers/Mongo.mjs'
 import Modules from '../../infrastructure/Modules.js'
 import Modules from '../../infrastructure/Modules.js'
 import FeaturesHelper from '../Subscription/FeaturesHelper.mjs'
 import FeaturesHelper from '../Subscription/FeaturesHelper.mjs'
 import AsyncLocalStorage from '../../infrastructure/AsyncLocalStorage.js'
 import AsyncLocalStorage from '../../infrastructure/AsyncLocalStorage.js'
 
 
+const { normalizeQuery, normalizeMultiQuery } = Mongo
 const InstitutionsAPIPromises = InstitutionsAPI.promises
 const InstitutionsAPIPromises = InstitutionsAPI.promises
 
 
 function _lastDayToReconfirm(emailData, institutionData) {
 function _lastDayToReconfirm(emailData, institutionData) {

+ 1 - 1
services/web/app/src/Features/User/UserOnboardingEmailManager.mjs

@@ -1,4 +1,4 @@
-import Queues from '../../infrastructure/Queues.js'
+import Queues from '../../infrastructure/Queues.mjs'
 import EmailHandler from '../Email/EmailHandler.mjs'
 import EmailHandler from '../Email/EmailHandler.mjs'
 import UserUpdater from './UserUpdater.mjs'
 import UserUpdater from './UserUpdater.mjs'
 import UserGetter from './UserGetter.mjs'
 import UserGetter from './UserGetter.mjs'

+ 1 - 1
services/web/app/src/Features/User/UserPagesController.mjs

@@ -9,7 +9,7 @@ import NewsletterManager from '../Newsletter/NewsletterManager.mjs'
 import SubscriptionLocator from '../Subscription/SubscriptionLocator.mjs'
 import SubscriptionLocator from '../Subscription/SubscriptionLocator.mjs'
 import _ from 'lodash'
 import _ from 'lodash'
 import { expressify } from '@overleaf/promise-utils'
 import { expressify } from '@overleaf/promise-utils'
-import Features from '../../infrastructure/Features.js'
+import Features from '../../infrastructure/Features.mjs'
 import Modules from '../../infrastructure/Modules.js'
 import Modules from '../../infrastructure/Modules.js'
 
 
 async function settingsPage(req, res) {
 async function settingsPage(req, res) {

+ 1 - 1
services/web/app/src/Features/User/UserPostRegistrationAnalyticsManager.mjs

@@ -1,4 +1,4 @@
-import Queues from '../../infrastructure/Queues.js'
+import Queues from '../../infrastructure/Queues.mjs'
 import UserGetter from './UserGetter.mjs'
 import UserGetter from './UserGetter.mjs'
 import InstitutionsAPI from '../Institutions/InstitutionsAPI.mjs'
 import InstitutionsAPI from '../Institutions/InstitutionsAPI.mjs'
 import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
 import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'

+ 4 - 2
services/web/app/src/Features/User/UserUpdater.mjs

@@ -1,11 +1,11 @@
 import logger from '@overleaf/logger'
 import logger from '@overleaf/logger'
 import OError from '@overleaf/o-error'
 import OError from '@overleaf/o-error'
 import { db } from '../../infrastructure/mongodb.js'
 import { db } from '../../infrastructure/mongodb.js'
-import { normalizeQuery } from '../Helpers/Mongo.js'
+import Mongo from '../Helpers/Mongo.mjs'
 import { callbackify } from 'node:util'
 import { callbackify } from 'node:util'
 import UserGetter from './UserGetter.mjs'
 import UserGetter from './UserGetter.mjs'
 import InstitutionsAPI from '../Institutions/InstitutionsAPI.mjs'
 import InstitutionsAPI from '../Institutions/InstitutionsAPI.mjs'
-import Features from '../../infrastructure/Features.js'
+import Features from '../../infrastructure/Features.mjs'
 import FeaturesUpdater from '../Subscription/FeaturesUpdater.mjs'
 import FeaturesUpdater from '../Subscription/FeaturesUpdater.mjs'
 import EmailHandler from '../Email/EmailHandler.mjs'
 import EmailHandler from '../Email/EmailHandler.mjs'
 import EmailHelper from '../Helpers/EmailHelper.mjs'
 import EmailHelper from '../Helpers/EmailHelper.mjs'
@@ -22,6 +22,8 @@ import UserSessionsManager from './UserSessionsManager.mjs'
 import ThirdPartyIdentityManager from './ThirdPartyIdentityManager.mjs'
 import ThirdPartyIdentityManager from './ThirdPartyIdentityManager.mjs'
 import AsyncLocalStorage from '../../infrastructure/AsyncLocalStorage.js'
 import AsyncLocalStorage from '../../infrastructure/AsyncLocalStorage.js'
 
 
+const { normalizeQuery } = Mongo
+
 async function _sendSecurityAlertPrimaryEmailChanged(
 async function _sendSecurityAlertPrimaryEmailChanged(
   userId,
   userId,
   oldEmail,
   oldEmail,

+ 3 - 1
services/web/app/src/Features/UserMembership/UserMembershipViewModel.mjs

@@ -1,5 +1,7 @@
 import UserGetter from '../User/UserGetter.mjs'
 import UserGetter from '../User/UserGetter.mjs'
-import { isObjectIdInstance } from '../Helpers/Mongo.js'
+import Mongo from '../Helpers/Mongo.mjs'
+
+const { isObjectIdInstance } = Mongo
 
 
 const UserMembershipViewModel = {
 const UserMembershipViewModel = {
   build(userOrEmail) {
   build(userOrEmail) {

+ 6 - 5
services/web/app/src/Features/V1/V1Api.js → services/web/app/src/Features/V1/V1Api.mjs

@@ -7,10 +7,11 @@
  * DS207: Consider shorter variations of null checks
  * DS207: Consider shorter variations of null checks
  * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  */
  */
-const request = require('request')
-const settings = require('@overleaf/settings')
-const Errors = require('../Errors/Errors')
-const { promisifyAll } = require('@overleaf/promise-utils')
+import request from 'request'
+
+import settings from '@overleaf/settings'
+import Errors from '../Errors/Errors.js'
+import { promisifyAll } from '@overleaf/promise-utils'
 
 
 // TODO: check what happens when these settings aren't defined
 // TODO: check what happens when these settings aren't defined
 const DEFAULT_V1_PARAMS = {
 const DEFAULT_V1_PARAMS = {
@@ -103,4 +104,4 @@ V1Api.promises = promisifyAll(V1Api, {
     oauthRequest: ['response', 'body'],
     oauthRequest: ['response', 'body'],
   },
   },
 })
 })
-module.exports = V1Api
+export default V1Api

+ 1 - 1
services/web/app/src/Features/V1/V1Handler.mjs

@@ -11,7 +11,7 @@
  * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  */
  */
 import OError from '@overleaf/o-error'
 import OError from '@overleaf/o-error'
-import V1Api from './V1Api.js'
+import V1Api from './V1Api.mjs'
 import logger from '@overleaf/logger'
 import logger from '@overleaf/logger'
 
 
 let V1Handler
 let V1Handler

+ 1 - 1
services/web/app/src/infrastructure/ExpressLocals.mjs

@@ -6,7 +6,7 @@ import Path from 'node:path'
 import moment from 'moment'
 import moment from 'moment'
 import { fetchJson } from '@overleaf/fetch-utils'
 import { fetchJson } from '@overleaf/fetch-utils'
 import contentDisposition from 'content-disposition'
 import contentDisposition from 'content-disposition'
-import Features from './Features.js'
+import Features from './Features.mjs'
 import SessionManager from '../Features/Authentication/SessionManager.mjs'
 import SessionManager from '../Features/Authentication/SessionManager.mjs'
 import PackageVersions from './PackageVersions.js'
 import PackageVersions from './PackageVersions.js'
 import Modules from './Modules.js'
 import Modules from './Modules.js'

+ 3 - 3
services/web/app/src/infrastructure/Features.js → services/web/app/src/infrastructure/Features.mjs

@@ -1,5 +1,5 @@
-const _ = require('lodash')
-const Settings = require('@overleaf/settings')
+import _ from 'lodash'
+import Settings from '@overleaf/settings'
 
 
 const supportModuleAvailable = Settings.moduleImportSequence.includes('support')
 const supportModuleAvailable = Settings.moduleImportSequence.includes('support')
 
 
@@ -98,4 +98,4 @@ const Features = {
   },
   },
 }
 }
 
 
-module.exports = Features
+export default Features

+ 2 - 2
services/web/app/src/infrastructure/QueueWorkers.mjs

@@ -1,5 +1,5 @@
-import Features from './Features.js'
-import Queues from './Queues.js'
+import Features from './Features.mjs'
+import Queues from './Queues.mjs'
 import UserOnboardingEmailManager from '../Features/User/UserOnboardingEmailManager.mjs'
 import UserOnboardingEmailManager from '../Features/User/UserOnboardingEmailManager.mjs'
 import UserPostRegistrationAnalyticsManager from '../Features/User/UserPostRegistrationAnalyticsManager.mjs'
 import UserPostRegistrationAnalyticsManager from '../Features/User/UserPostRegistrationAnalyticsManager.mjs'
 import FeaturesUpdater from '../Features/Subscription/FeaturesUpdater.mjs'
 import FeaturesUpdater from '../Features/Subscription/FeaturesUpdater.mjs'

+ 5 - 5
services/web/app/src/infrastructure/Queues.js → services/web/app/src/infrastructure/Queues.mjs

@@ -1,7 +1,7 @@
-const Queue = require('bull')
-const Settings = require('@overleaf/settings')
-const Features = require('../infrastructure/Features')
-const { addConnectionDrainer } = require('./GracefulShutdown')
+import Queue from 'bull'
+import Settings from '@overleaf/settings'
+import Features from '../infrastructure/Features.mjs'
+import { addConnectionDrainer } from './GracefulShutdown.js'
 
 
 // Bull will keep a fixed number of the most recently completed jobs. This is
 // Bull will keep a fixed number of the most recently completed jobs. This is
 // useful to inspect recently completed jobs. The bull prometheus exporter also
 // useful to inspect recently completed jobs. The bull prometheus exporter also
@@ -127,7 +127,7 @@ async function createScheduledJob(queueName, { name, data, options }, delay) {
   )
   )
 }
 }
 
 
-module.exports = {
+export default {
   getQueue,
   getQueue,
   createScheduledJob,
   createScheduledJob,
 }
 }

+ 1 - 1
services/web/app/src/infrastructure/Server.mjs

@@ -23,7 +23,7 @@ import ReferalConnect from '../Features/Referal/ReferalConnect.mjs'
 import RedirectManager from './RedirectManager.mjs'
 import RedirectManager from './RedirectManager.mjs'
 import translations from './Translations.mjs'
 import translations from './Translations.mjs'
 import Views from './Views.js'
 import Views from './Views.js'
-import Features from './Features.js'
+import Features from './Features.mjs'
 import ErrorController from '../Features/Errors/ErrorController.mjs'
 import ErrorController from '../Features/Errors/ErrorController.mjs'
 import HttpErrorHandler from '../Features/Errors/HttpErrorHandler.mjs'
 import HttpErrorHandler from '../Features/Errors/HttpErrorHandler.mjs'
 import UserSessionsManager from '../Features/User/UserSessionsManager.mjs'
 import UserSessionsManager from '../Features/User/UserSessionsManager.mjs'

+ 1 - 1
services/web/app/src/infrastructure/SiteAdminHandler.mjs

@@ -7,7 +7,7 @@ import {
   addRequiredCleanupHandlerBeforeDrainingConnections,
   addRequiredCleanupHandlerBeforeDrainingConnections,
 } from './GracefulShutdown.js'
 } from './GracefulShutdown.js'
 
 
-import Features from './Features.js'
+import Features from './Features.mjs'
 import UserHandler from '../Features/User/UserHandler.mjs'
 import UserHandler from '../Features/User/UserHandler.mjs'
 import metrics from '@overleaf/metrics'
 import metrics from '@overleaf/metrics'
 
 

+ 1 - 1
services/web/app/src/models/User.mjs

@@ -1,6 +1,6 @@
 import Settings from '@overleaf/settings'
 import Settings from '@overleaf/settings'
 import mongoose from '../infrastructure/Mongoose.js'
 import mongoose from '../infrastructure/Mongoose.js'
-import TokenGenerator from '../Features/TokenGenerator/TokenGenerator.js'
+import TokenGenerator from '../Features/TokenGenerator/TokenGenerator.mjs'
 const { Schema } = mongoose
 const { Schema } = mongoose
 const { ObjectId } = Schema
 const { ObjectId } = Schema
 
 

+ 1 - 1
services/web/app/src/router.mjs

@@ -1,6 +1,6 @@
 import AdminController from './Features/ServerAdmin/AdminController.mjs'
 import AdminController from './Features/ServerAdmin/AdminController.mjs'
 import ErrorController from './Features/Errors/ErrorController.mjs'
 import ErrorController from './Features/Errors/ErrorController.mjs'
-import Features from './infrastructure/Features.js'
+import Features from './infrastructure/Features.mjs'
 import ProjectController from './Features/Project/ProjectController.mjs'
 import ProjectController from './Features/Project/ProjectController.mjs'
 import ProjectApiController from './Features/Project/ProjectApiController.mjs'
 import ProjectApiController from './Features/Project/ProjectApiController.mjs'
 import ProjectListController from './Features/Project/ProjectListController.mjs'
 import ProjectListController from './Features/Project/ProjectListController.mjs'

+ 2 - 1
services/web/scripts/backfill_mixpanel_user_properties.mjs

@@ -2,12 +2,13 @@
 import '../app/src/models/User.mjs'
 import '../app/src/models/User.mjs'
 import { batchedUpdateWithResultHandling } from '@overleaf/mongo-utils/batchedUpdate.js'
 import { batchedUpdateWithResultHandling } from '@overleaf/mongo-utils/batchedUpdate.js'
 import { promiseMapWithLimit } from '@overleaf/promise-utils'
 import { promiseMapWithLimit } from '@overleaf/promise-utils'
-import { getQueue } from '../app/src/infrastructure/Queues.js'
+import Queues from '../app/src/infrastructure/Queues.mjs'
 import SubscriptionLocator from '../app/src/Features/Subscription/SubscriptionLocator.mjs'
 import SubscriptionLocator from '../app/src/Features/Subscription/SubscriptionLocator.mjs'
 import PlansLocator from '../app/src/Features/Subscription/PlansLocator.mjs'
 import PlansLocator from '../app/src/Features/Subscription/PlansLocator.mjs'
 import FeaturesHelper from '../app/src/Features/Subscription/FeaturesHelper.mjs'
 import FeaturesHelper from '../app/src/Features/Subscription/FeaturesHelper.mjs'
 import { db } from '../app/src/infrastructure/mongodb.js'
 import { db } from '../app/src/infrastructure/mongodb.js'
 
 
+const { getQueue } = Queues
 const WRITE_CONCURRENCY = parseInt(process.env.WRITE_CONCURRENCY || '10', 10)
 const WRITE_CONCURRENCY = parseInt(process.env.WRITE_CONCURRENCY || '10', 10)
 
 
 const mixpanelSinkQueue = getQueue('analytics-mixpanel-sink')
 const mixpanelSinkQueue = getQueue('analytics-mixpanel-sink')

+ 1 - 1
services/web/scripts/regenerate_duplicate_referral_ids.mjs

@@ -3,7 +3,7 @@ import {
   READ_PREFERENCE_SECONDARY,
   READ_PREFERENCE_SECONDARY,
 } from '../app/src/infrastructure/mongodb.js'
 } from '../app/src/infrastructure/mongodb.js'
 import { promiseMapWithLimit } from '@overleaf/promise-utils'
 import { promiseMapWithLimit } from '@overleaf/promise-utils'
-import TokenGenerator from '../app/src/Features/TokenGenerator/TokenGenerator.js'
+import TokenGenerator from '../app/src/Features/TokenGenerator/TokenGenerator.mjs'
 import { batchedUpdate } from '@overleaf/mongo-utils/batchedUpdate.js'
 import { batchedUpdate } from '@overleaf/mongo-utils/batchedUpdate.js'
 
 
 const VERBOSE_LOGGING = process.env.VERBOSE_LOGGING === 'true'
 const VERBOSE_LOGGING = process.env.VERBOSE_LOGGING === 'true'

+ 1 - 1
services/web/test/acceptance/src/ActiveUsersMetricTests.mjs

@@ -1,6 +1,6 @@
 import { promisify } from 'node:util'
 import { promisify } from 'node:util'
 import { expect } from 'chai'
 import { expect } from 'chai'
-import Features from '../../../app/src/infrastructure/Features.js'
+import Features from '../../../app/src/infrastructure/Features.mjs'
 import MetricsHelper from './helpers/metrics.mjs'
 import MetricsHelper from './helpers/metrics.mjs'
 import UserHelper from './helpers/User.mjs'
 import UserHelper from './helpers/User.mjs'
 const sleep = promisify(setTimeout)
 const sleep = promisify(setTimeout)

+ 1 - 1
services/web/test/acceptance/src/AddSecondaryEmailTests.mjs

@@ -3,7 +3,7 @@ import UserHelper from './helpers/User.mjs'
 import logger from '@overleaf/logger'
 import logger from '@overleaf/logger'
 import sinon from 'sinon'
 import sinon from 'sinon'
 import { db } from '../../../app/src/infrastructure/mongodb.js'
 import { db } from '../../../app/src/infrastructure/mongodb.js'
-import Features from '../../../app/src/infrastructure/Features.js'
+import Features from '../../../app/src/infrastructure/Features.mjs'
 
 
 const User = UserHelper.promises
 const User = UserHelper.promises
 
 

+ 1 - 1
services/web/test/acceptance/src/AuthorizationTests.mjs

@@ -2,7 +2,7 @@ import { expect } from 'chai'
 import UserHelper from './helpers/User.mjs'
 import UserHelper from './helpers/User.mjs'
 import request from './helpers/request.js'
 import request from './helpers/request.js'
 import settings from '@overleaf/settings'
 import settings from '@overleaf/settings'
-import Features from '../../../app/src/infrastructure/Features.js'
+import Features from '../../../app/src/infrastructure/Features.mjs'
 import expectErrorResponse from './helpers/expectErrorResponse.mjs'
 import expectErrorResponse from './helpers/expectErrorResponse.mjs'
 import { promisify } from '@overleaf/promise-utils'
 import { promisify } from '@overleaf/promise-utils'
 
 

+ 1 - 1
services/web/test/acceptance/src/DeletionTests.mjs

@@ -7,7 +7,7 @@ import async from 'async'
 import { expect } from 'chai'
 import { expect } from 'chai'
 import settings from '@overleaf/settings'
 import settings from '@overleaf/settings'
 import { db, ObjectId } from '../../../app/src/infrastructure/mongodb.js'
 import { db, ObjectId } from '../../../app/src/infrastructure/mongodb.js'
-import Features from '../../../app/src/infrastructure/Features.js'
+import Features from '../../../app/src/infrastructure/Features.mjs'
 import MockDocstoreApiClass from './mocks/MockDocstoreApi.mjs'
 import MockDocstoreApiClass from './mocks/MockDocstoreApi.mjs'
 import MockChatApiClass from './mocks/MockChatApi.mjs'
 import MockChatApiClass from './mocks/MockChatApi.mjs'
 import MockGitBridgeApiClass from './mocks/MockGitBridgeApi.mjs'
 import MockGitBridgeApiClass from './mocks/MockGitBridgeApi.mjs'

+ 1 - 1
services/web/test/acceptance/src/Init.mjs

@@ -1,5 +1,5 @@
 import './helpers/InitApp.mjs'
 import './helpers/InitApp.mjs'
-import Features from '../../../app/src/infrastructure/Features.js'
+import Features from '../../../app/src/infrastructure/Features.mjs'
 
 
 import MockAnalyticsApi from './mocks/MockAnalyticsApi.mjs'
 import MockAnalyticsApi from './mocks/MockAnalyticsApi.mjs'
 import MockChatApi from './mocks/MockChatApi.mjs'
 import MockChatApi from './mocks/MockChatApi.mjs'

+ 3 - 4
services/web/test/acceptance/src/MongoHelper.mjs

@@ -3,12 +3,11 @@ import mongodb from 'mongodb-legacy'
 import mongoose from 'mongoose'
 import mongoose from 'mongoose'
 import { User as UserModel } from '../../../app/src/models/User.mjs'
 import { User as UserModel } from '../../../app/src/models/User.mjs'
 import { db } from '../../../app/src/infrastructure/mongodb.js'
 import { db } from '../../../app/src/infrastructure/mongodb.js'
-import {
-  normalizeQuery,
-  normalizeMultiQuery,
-} from '../../../app/src/Features/Helpers/Mongo.js'
+import MongoHelpers from '../../../app/src/Features/Helpers/Mongo.mjs'
 import UserHelper from './helpers/User.mjs'
 import UserHelper from './helpers/User.mjs'
 
 
+const { normalizeQuery, normalizeMultiQuery } = MongoHelpers
+
 const User = UserHelper.promises
 const User = UserHelper.promises
 
 
 const NativeObjectId = mongodb.ObjectId
 const NativeObjectId = mongodb.ObjectId

+ 1 - 1
services/web/test/acceptance/src/PrimaryEmailCheckTests.mjs

@@ -1,7 +1,7 @@
 import UserHelper from './helpers/UserHelper.mjs'
 import UserHelper from './helpers/UserHelper.mjs'
 import Settings from '@overleaf/settings'
 import Settings from '@overleaf/settings'
 import { expect } from 'chai'
 import { expect } from 'chai'
-import Features from '../../../app/src/infrastructure/Features.js'
+import Features from '../../../app/src/infrastructure/Features.mjs'
 import MockV1ApiClass from './mocks/MockV1Api.mjs'
 import MockV1ApiClass from './mocks/MockV1Api.mjs'
 import SubscriptionHelper from './helpers/Subscription.mjs'
 import SubscriptionHelper from './helpers/Subscription.mjs'
 
 

+ 1 - 1
services/web/test/acceptance/src/ProjectCRUDTests.mjs

@@ -4,7 +4,7 @@ import { Project } from '../../../app/src/models/Project.mjs'
 import mongodb from 'mongodb-legacy'
 import mongodb from 'mongodb-legacy'
 import cheerio from 'cheerio'
 import cheerio from 'cheerio'
 import { Subscription } from '../../../app/src/models/Subscription.mjs'
 import { Subscription } from '../../../app/src/models/Subscription.mjs'
-import Features from '../../../app/src/infrastructure/Features.js'
+import Features from '../../../app/src/infrastructure/Features.mjs'
 
 
 const ObjectId = mongodb.ObjectId
 const ObjectId = mongodb.ObjectId
 
 

+ 1 - 1
services/web/test/acceptance/src/ProjectInviteTests.mjs

@@ -4,7 +4,7 @@ import User from './helpers/User.mjs'
 import settings from '@overleaf/settings'
 import settings from '@overleaf/settings'
 import CollaboratorsEmailHandler from '../../../app/src/Features/Collaborators/CollaboratorsEmailHandler.mjs'
 import CollaboratorsEmailHandler from '../../../app/src/Features/Collaborators/CollaboratorsEmailHandler.mjs'
 import CollaboratorsInviteHelper from '../../../app/src/Features/Collaborators/CollaboratorsInviteHelper.mjs'
 import CollaboratorsInviteHelper from '../../../app/src/Features/Collaborators/CollaboratorsInviteHelper.mjs'
-import Features from '../../../app/src/infrastructure/Features.js'
+import Features from '../../../app/src/infrastructure/Features.mjs'
 import sinon from 'sinon'
 import sinon from 'sinon'
 
 
 let generateTokenSpy
 let generateTokenSpy

+ 1 - 1
services/web/test/acceptance/src/RegistrationTests.mjs

@@ -3,7 +3,7 @@ import async from 'async'
 import metrics from './helpers/metrics.mjs'
 import metrics from './helpers/metrics.mjs'
 import User from './helpers/User.mjs'
 import User from './helpers/User.mjs'
 import redis from './helpers/redis.mjs'
 import redis from './helpers/redis.mjs'
-import Features from '../../../app/src/infrastructure/Features.js'
+import Features from '../../../app/src/infrastructure/Features.mjs'
 
 
 const UserPromises = User.promises
 const UserPromises = User.promises
 
 

+ 1 - 1
services/web/test/acceptance/src/SettingsTests.mjs

@@ -12,7 +12,7 @@ import { expect } from 'chai'
 
 
 import async from 'async'
 import async from 'async'
 import User from './helpers/User.mjs'
 import User from './helpers/User.mjs'
-import Features from '../../../app/src/infrastructure/Features.js'
+import Features from '../../../app/src/infrastructure/Features.mjs'
 
 
 describe('SettingsPage', function () {
 describe('SettingsPage', function () {
   beforeEach(function (done) {
   beforeEach(function (done) {

+ 1 - 1
services/web/test/acceptance/src/UserHelperTests.mjs

@@ -1,6 +1,6 @@
 import AuthenticationManager from '../../../app/src/Features/Authentication/AuthenticationManager.mjs'
 import AuthenticationManager from '../../../app/src/Features/Authentication/AuthenticationManager.mjs'
 import UserHelper from './helpers/UserHelper.mjs'
 import UserHelper from './helpers/UserHelper.mjs'
-import Features from '../../../app/src/infrastructure/Features.js'
+import Features from '../../../app/src/infrastructure/Features.mjs'
 import { expect } from 'chai'
 import { expect } from 'chai'
 
 
 describe('UserHelper', function () {
 describe('UserHelper', function () {

+ 1 - 1
services/web/test/smoke/src/steps/001_clearRateLimits.mjs

@@ -3,7 +3,7 @@ import {
   overleafLoginRateLimiter,
   overleafLoginRateLimiter,
   openProjectRateLimiter,
   openProjectRateLimiter,
 } from '../../../../app/src/infrastructure/RateLimiter.js'
 } from '../../../../app/src/infrastructure/RateLimiter.js'
-import LoginRateLimiter from '../../../../app/src/Features/Security/LoginRateLimiter.js'
+import LoginRateLimiter from '../../../../app/src/Features/Security/LoginRateLimiter.mjs'
 
 
 async function clearLoginRateLimit() {
 async function clearLoginRateLimit() {
   await LoginRateLimiter.promises.recordSuccessfulLogin(Settings.smokeTest.user)
   await LoginRateLimiter.promises.recordSuccessfulLogin(Settings.smokeTest.user)

+ 1 - 4
services/web/test/unit/bootstrap.js

@@ -66,10 +66,7 @@ function getSandboxedModuleRequires() {
     '@overleaf/logger': globalStubs.logger,
     '@overleaf/logger': globalStubs.logger,
   }
   }
 
 
-  const internalModules = [
-    '../../app/src/Features/Errors/Errors',
-    '../../app/src/Features/Helpers/Mongo',
-  ]
+  const internalModules = ['../../app/src/Features/Errors/Errors']
   const externalLibs = [
   const externalLibs = [
     'async',
     'async',
     'bull',
     'bull',

+ 3 - 3
services/web/test/unit/src/Analytics/AnalyticsController.test.mjs

@@ -1,6 +1,6 @@
 import { vi } from 'vitest'
 import { vi } from 'vitest'
 import sinon from 'sinon'
 import sinon from 'sinon'
-import MockResponse from '../helpers/MockResponse.js'
+import MockResponse from '../helpers/MockResponseVitest.mjs'
 const modulePath = new URL(
 const modulePath = new URL(
   '../../../../app/src/Features/Analytics/AnalyticsController.mjs',
   '../../../../app/src/Features/Analytics/AnalyticsController.mjs',
   import.meta.url
   import.meta.url
@@ -33,7 +33,7 @@ describe('AnalyticsController', function () {
       })
       })
     )
     )
 
 
-    vi.doMock('../../../../app/src/infrastructure/Features.js', () => ({
+    vi.doMock('../../../../app/src/infrastructure/Features.mjs', () => ({
       default: ctx.Features,
       default: ctx.Features,
     }))
     }))
 
 
@@ -47,7 +47,7 @@ describe('AnalyticsController', function () {
 
 
     ctx.controller = (await import(modulePath)).default
     ctx.controller = (await import(modulePath)).default
 
 
-    ctx.res = new MockResponse()
+    ctx.res = new MockResponse(vi)
   })
   })
 
 
   describe('updateEditingSession', function () {
   describe('updateEditingSession', function () {

+ 5 - 5
services/web/test/unit/src/Analytics/AnalyticsManager.test.mjs

@@ -1,8 +1,8 @@
 import { vi, assert } from 'vitest'
 import { vi, assert } from 'vitest'
-import path from 'path'
+import path from 'node:path'
 import sinon from 'sinon'
 import sinon from 'sinon'
-import MockRequest from '../helpers/MockRequest.js'
-import MockResponse from '../helpers/MockResponse.js'
+import MockRequest from '../helpers/MockRequestVitest.mjs'
+import MockResponse from '../helpers/MockResponseVitest.mjs'
 import mongodb from 'mongodb-legacy'
 import mongodb from 'mongodb-legacy'
 
 
 const { ObjectId } = mongodb
 const { ObjectId } = mongodb
@@ -395,9 +395,9 @@ describe('AnalyticsManager', function () {
       }))
       }))
 
 
       ctx.AnalyticsManager = (await import(MODULE_PATH)).default
       ctx.AnalyticsManager = (await import(MODULE_PATH)).default
-      ctx.req = new MockRequest()
+      ctx.req = new MockRequest(vi)
       ctx.req.session = {}
       ctx.req.session = {}
-      ctx.res = new MockResponse()
+      ctx.res = new MockResponse(vi)
       ctx.next = () => {}
       ctx.next = () => {}
     })
     })
 
 

+ 4 - 4
services/web/test/unit/src/Analytics/AnalyticsUTMTrackingMiddleware.test.mjs

@@ -1,7 +1,7 @@
 import { assert, vi } from 'vitest'
 import { assert, vi } from 'vitest'
 import sinon from 'sinon'
 import sinon from 'sinon'
-import MockRequest from '../helpers/MockRequest.js'
-import MockResponse from '../helpers/MockResponse.js'
+import MockRequest from '../helpers/MockRequestVitest.mjs'
+import MockResponse from '../helpers/MockResponseVitest.mjs'
 
 
 const MODULE_PATH = new URL(
 const MODULE_PATH = new URL(
   '../../../../app/src/Features/Analytics/AnalyticsUTMTrackingMiddleware',
   '../../../../app/src/Features/Analytics/AnalyticsUTMTrackingMiddleware',
@@ -13,8 +13,8 @@ describe('AnalyticsUTMTrackingMiddleware', function () {
     ctx.analyticsId = 'ecdb935a-52f3-4f91-aebc-7a70d2ffbb55'
     ctx.analyticsId = 'ecdb935a-52f3-4f91-aebc-7a70d2ffbb55'
     ctx.userId = '61795fcb013504bb7b663092'
     ctx.userId = '61795fcb013504bb7b663092'
 
 
-    ctx.req = new MockRequest()
-    ctx.res = new MockResponse()
+    ctx.req = new MockRequest(vi)
+    ctx.res = new MockResponse(vi)
     ctx.next = sinon.stub().returns()
     ctx.next = sinon.stub().returns()
     ctx.req.session = {
     ctx.req.session = {
       user: {
       user: {

+ 3 - 1
services/web/test/unit/src/Analytics/EmailChangeHelpers.test.mjs

@@ -29,7 +29,9 @@ describe('EmailChangeHelper', function () {
     )
     )
 
 
     EmailChangeHelpers = (
     EmailChangeHelpers = (
-      await import('../../../../app/src/Features/Analytics/EmailChangeHelper')
+      await import(
+        '../../../../app/src/Features/Analytics/EmailChangeHelper.mjs'
+      )
     ).default
     ).default
   })
   })
 
 

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません