Ver Fonte

Revert "Acf pnp migration master" (#34709)

GitOrigin-RevId: ec7d63e1212e05dd6dfc7a0ddf785c11eca76ad6
Anna Claire Fields há 1 mês atrás
pai
commit
7035a2e025
94 ficheiros alterados com 157 adições e 1069 exclusões
  1. 0 5
      .yarn/patches/esmock-npm-2.7.3-83624b28f6.patch
  2. 1 66
      .yarnrc.yml
  3. 1 0
      dockerfiles/cypress/Dockerfile
  4. 0 6
      libraries/access-token-encryptor/package.json
  5. 0 2
      libraries/fetch-utils/package.json
  6. 0 6
      libraries/logger/package.json
  7. 0 3
      libraries/metrics/package.json
  8. 0 6
      libraries/mongo-utils/package.json
  9. 0 1
      libraries/o-error/package.json
  10. 0 6
      libraries/object-persistor/package.json
  11. 0 8
      libraries/overleaf-editor-core/package.json
  12. 0 2
      libraries/promise-utils/package.json
  13. 0 3
      libraries/ranges-tracker/package.json
  14. 0 2
      libraries/redis-wrapper/package.json
  15. 2 12
      libraries/settings/Settings.js
  16. 0 2
      libraries/settings/package.json
  17. 0 2
      libraries/stream-utils/package.json
  18. 0 3
      libraries/validation-tools/package.json
  19. 1 13
      package.json
  20. 3 6
      server-ce/Dockerfile
  21. 0 1
      server-ce/test/.gitignore
  22. 1 0
      server-ce/test/Dockerfile
  23. 1 4
      server-ce/test/cypress.config.ts
  24. 8 12
      server-ce/test/docker-compose.yml
  25. 2 7
      server-ce/test/package.json
  26. 2 3
      services/chat/Dockerfile
  27. 3 5
      services/chat/Makefile
  28. 4 8
      services/chat/docker-compose.yml
  29. 0 2
      services/chat/package.json
  30. 1 1
      services/chat/test/acceptance/js/helpers/MongoHelper.js
  31. 7 8
      services/clsi/Dockerfile
  32. 3 5
      services/clsi/Makefile
  33. 4 8
      services/clsi/docker-compose.yml
  34. 0 2
      services/clsi/package.json
  35. 2 3
      services/docstore/Dockerfile
  36. 3 5
      services/docstore/Makefile
  37. 4 8
      services/docstore/docker-compose.yml
  38. 0 3
      services/docstore/package.json
  39. 1 1
      services/docstore/test/acceptance/js/helpers/MongoHelper.js
  40. 2 3
      services/document-updater/Dockerfile
  41. 3 5
      services/document-updater/Makefile
  42. 4 8
      services/document-updater/docker-compose.yml
  43. 0 5
      services/document-updater/package.json
  44. 1 4
      services/document-updater/scripts/flush_projects_with_no_history_id.js
  45. 1 1
      services/document-updater/test/acceptance/js/helpers/MongoHelper.js
  46. 3 4
      services/filestore/Dockerfile
  47. 3 5
      services/filestore/Makefile
  48. 4 8
      services/filestore/docker-compose.yml
  49. 0 2
      services/filestore/package.json
  50. 2 3
      services/history-v1/Dockerfile
  51. 3 5
      services/history-v1/Makefile
  52. 4 8
      services/history-v1/docker-compose.yml
  53. 0 6
      services/history-v1/package.json
  54. 2 3
      services/history-v1/storage/scripts/back_fill_file_hash.mjs
  55. 1 3
      services/history-v1/storage/scripts/fix_string_backedUpBlobs_ids.mjs
  56. 2 3
      services/history-v1/test/acceptance/js/storage/back_fill_file_hash.test.mjs
  57. 1 1
      services/history-v1/test/acceptance/js/storage/recover_zip.test.mjs
  58. 1 1
      services/history-v1/test/setup.js
  59. 2 3
      services/notifications/Dockerfile
  60. 3 5
      services/notifications/Makefile
  61. 4 8
      services/notifications/docker-compose.yml
  62. 0 3
      services/notifications/package.json
  63. 1 1
      services/notifications/test/acceptance/js/MongoHelper.ts
  64. 3 8
      services/project-history/Dockerfile
  65. 3 7
      services/project-history/Makefile
  66. 0 1
      services/project-history/buildscript.txt
  67. 4 8
      services/project-history/docker-compose.yml
  68. 1 5
      services/project-history/package.json
  69. 1 1
      services/project-history/test/acceptance/js/helpers/MongoHelper.js
  70. 2 3
      services/real-time/Dockerfile
  71. 3 5
      services/real-time/Makefile
  72. 4 8
      services/real-time/docker-compose.yml
  73. 0 3
      services/real-time/package.json
  74. 0 1
      services/web/.gitignore
  75. 0 3
      services/web/.storybook/main.ts
  76. 2 2
      services/web/Dockerfile
  77. 3 4
      services/web/Makefile
  78. 1 1
      services/web/bin/check_extracted_translations
  79. 1 4
      services/web/cypress.config.ts
  80. 9 22
      services/web/docker-compose.yml
  81. 3 26
      services/web/package.json
  82. 1 1
      services/web/scripts/learn/checkSanitize/checkSanitizeOptions.mjs
  83. 0 113
      services/web/scripts/materialize-cypress-reporter.js
  84. 2 2
      services/web/scripts/translations/cleanupUnusedLocales.js
  85. 0 12
      services/web/test/acceptance/bootstrap.js
  86. 1 2
      services/web/test/acceptance/src/DeleteOrphanedDocsOnlineCheckTests.mjs
  87. 1 1
      services/web/test/acceptance/src/helpers/MongoHelper.mjs
  88. 0 2
      services/web/test/unit/src/Settings/Settings.test.mjs
  89. 0 3
      services/web/tsconfig.json
  90. 0 11
      services/web/types/uppy-utils.d.ts
  91. 6 19
      services/web/webpack.config.js
  92. 0 3
      tools/migrations/package.json
  93. 0 1
      tsconfig.backend.json
  94. 5 449
      yarn.lock

Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 5
.yarn/patches/esmock-npm-2.7.3-83624b28f6.patch


+ 1 - 66
.yarnrc.yml

@@ -7,75 +7,10 @@ enableScripts: true
 
 enableTelemetry: false
 
-nodeLinker: pnp
+nodeLinker: node-modules
 
 npmMinimalAgeGate: 3d
 
-packageExtensions:
-  "bootstrap@*":
-    dependencies:
-      "@popperjs/core": "*"
-      jquery: "*"
-  "@overleaf/settings@*":
-    peerDependencies:
-      "@overleaf/logger": "*"
-  "mongodb@*":
-    peerDependencies:
-      aws4: "*"
-  "bunyan@*":
-    peerDependencies:
-      source-map-support: "*"
-  "mocha-multi-reporters@*":
-    peerDependencies:
-      mocha-junit-reporter: "*"
-  "mongodb-legacy@*":
-    peerDependencies:
-      mongodb: "*"
-  "knex@*":
-    dependencies:
-      pg-query-stream: "*"
-  "zod-validation-error@*":
-    peerDependencies:
-      zod: "*"
-  "@vitejs/plugin-react@*":
-    peerDependencies:
-      vite: "*"
-  "@babel/preset-env@*":
-    peerDependencies:
-      core-js: "*"
-  "express@*":
-    dependencies:
-      pug: "*"
-  "postcss-loader@*":
-    peerDependencies:
-      autoprefixer: "*"
-      tailwindcss: "*"
-  "@ai-sdk/gateway@*":
-    peerDependencies:
-      zod: "*"
-  "@ai-sdk/provider-utils@*":
-    peerDependencies:
-      zod: "*"
-  "ai@*":
-    peerDependencies:
-      zod: "*"
-  "@uppy/react@*":
-    peerDependencies:
-      "@uppy/status-bar": "*"
-  "inversify@*":
-    dependencies:
-      reflect-metadata: "*"
-  "sinon-mongoose@*":
-    dependencies:
-      mongoose: "*"
-  "react-linkify@*":
-    peerDependencies:
-      react: "*"
-  "debug@*":
-    peerDependenciesMeta:
-      supports-color:
-        optional: true
-
 supportedArchitectures:
   cpu:
     - current

+ 1 - 0
dockerfiles/cypress/Dockerfile

@@ -3,6 +3,7 @@ ARG USER_UID=1000
 ARG USER_GID=1000
 
 # Corepack setup, shared between all the images.
+ENV PATH="/overleaf/node_modules/.bin:$PATH"
 ENV COREPACK_HOME=/opt/corepack
 RUN corepack enable && corepack install -g yarn@4.14.1
 ENV COREPACK_ENABLE_NETWORK=0

+ 0 - 6
libraries/access-token-encryptor/package.json

@@ -3,10 +3,6 @@
   "version": "3.0.0",
   "description": "",
   "main": "index.js",
-  "exports": {
-    ".": "./index.js",
-    "./*": "./*"
-  },
   "scripts": {
     "test": "yarn run lint && yarn run types:check && yarn run test:unit",
     "lint": "eslint --cache --cache-location ../../.cache/eslint/ --ext .cjs,.js,.jsx,.mjs,.ts --max-warnings 0 --format unix .",
@@ -21,10 +17,8 @@
     "lodash": "^4.18.1"
   },
   "devDependencies": {
-    "@types/node": "^24.5.2",
     "chai": "^4.3.6",
     "chai-as-promised": "^7.1.1",
-    "eslint": "^10.4.0",
     "mocha": "^11.1.0",
     "mocha-junit-reporter": "^2.2.1",
     "mocha-multi-reporters": "^1.5.1",

+ 0 - 2
libraries/fetch-utils/package.json

@@ -14,12 +14,10 @@
   "author": "Overleaf (https://www.overleaf.com)",
   "license": "AGPL-3.0-only",
   "devDependencies": {
-    "@types/node": "^24.5.2",
     "@types/node-fetch": "^2.6.13",
     "body-parser": "1.20.4",
     "chai": "^4.3.6",
     "chai-as-promised": "^7.1.1",
-    "eslint": "^10.4.0",
     "express": "4.22.1",
     "mocha": "^11.1.0",
     "mocha-junit-reporter": "^2.2.1",

+ 0 - 6
libraries/logger/package.json

@@ -7,10 +7,6 @@
     "url": "https://github.com/overleaf/overleaf"
   },
   "main": "index.js",
-  "exports": {
-    ".": "./index.js",
-    "./*": "./*"
-  },
   "license": "AGPL-3.0-only",
   "version": "3.1.1",
   "scripts": {
@@ -28,9 +24,7 @@
     "bunyan": "^1.8.14"
   },
   "devDependencies": {
-    "@types/node": "^24.5.2",
     "chai": "^4.3.6",
-    "eslint": "^10.4.0",
     "mocha": "^11.1.0",
     "mocha-junit-reporter": "^2.2.1",
     "mocha-multi-reporters": "^1.5.1",

+ 0 - 3
libraries/metrics/package.json

@@ -21,11 +21,8 @@
     "yn": "^3.1.1"
   },
   "devDependencies": {
-    "@overleaf/logger": "workspace:*",
-    "@types/node": "^24.5.2",
     "bunyan": "^1.0.0",
     "chai": "^4.3.6",
-    "eslint": "^10.4.0",
     "mocha": "^11.1.0",
     "mocha-junit-reporter": "^2.2.1",
     "mocha-multi-reporters": "^1.5.1",

+ 0 - 6
libraries/mongo-utils/package.json

@@ -3,10 +3,6 @@
   "version": "0.0.1",
   "description": "utilities to help working with mongo",
   "main": "index.js",
-  "exports": {
-    ".": "./index.js",
-    "./*": "./*"
-  },
   "scripts": {
     "test": "yarn run lint && yarn run types:check && yarn run test:unit",
     "test:unit": "mocha --exit test/**/*.{js,cjs}",
@@ -22,9 +18,7 @@
     "mongodb-legacy": "6.1.3"
   },
   "devDependencies": {
-    "@types/node": "^24.5.2",
     "chai": "^4.3.6",
-    "eslint": "^10.4.0",
     "mocha": "^11.1.0",
     "mocha-junit-reporter": "^2.2.1",
     "mocha-multi-reporters": "^1.5.1",

+ 0 - 1
libraries/o-error/package.json

@@ -32,7 +32,6 @@
     "@types/chai": "^4.3.0",
     "@types/node": "^24.5.2",
     "chai": "^4.3.6",
-    "eslint": "^10.4.0",
     "mocha": "^11.1.0",
     "mocha-junit-reporter": "^2.2.1",
     "mocha-multi-reporters": "^1.5.1",

+ 0 - 6
libraries/object-persistor/package.json

@@ -3,10 +3,6 @@
   "version": "1.0.2",
   "description": "Module for storing objects in multiple backends, with fallback on 404 to assist migration between them",
   "main": "index.js",
-  "exports": {
-    ".": "./index.js",
-    "./*": "./*"
-  },
   "scripts": {
     "test": "yarn run lint && yarn run types:check && yarn run test:unit",
     "test:unit": "mocha --exit test/**/*.{js,cjs}",
@@ -37,10 +33,8 @@
     "tiny-async-pool": "^1.1.0"
   },
   "devDependencies": {
-    "@types/node": "^24.5.2",
     "chai": "^4.3.6",
     "chai-as-promised": "^7.1.1",
-    "eslint": "^10.4.0",
     "mocha": "^11.1.0",
     "mocha-junit-reporter": "^2.2.1",
     "mocha-multi-reporters": "^1.5.1",

+ 0 - 8
libraries/overleaf-editor-core/package.json

@@ -3,10 +3,6 @@
   "version": "1.0.0",
   "description": "Library shared between the editor server and clients.",
   "main": "index.js",
-  "exports": {
-    ".": "./index.js",
-    "./*": "./*"
-  },
   "scripts": {
     "test": "yarn run lint && yarn run types:check && yarn run test:unit",
     "lint": "eslint --cache --cache-location ../../.cache/eslint/ --ext .cjs,.js,.jsx,.mjs,.ts --max-warnings 0 --format unix .",
@@ -20,12 +16,8 @@
   "private": true,
   "devDependencies": {
     "@types/check-types": "^7.3.7",
-    "@types/lodash": "^4.17.24",
-    "@types/mocha": "^10.0.6",
-    "@types/node": "^24.5.2",
     "@types/path-browserify": "^1.0.3",
     "chai": "^3.3.0",
-    "eslint": "^10.4.0",
     "mocha": "^11.1.0",
     "mocha-junit-reporter": "^2.2.1",
     "mocha-multi-reporters": "^1.5.1",

+ 0 - 2
libraries/promise-utils/package.json

@@ -14,10 +14,8 @@
   "author": "Overleaf (https://www.overleaf.com)",
   "license": "AGPL-3.0-only",
   "devDependencies": {
-    "@types/node": "^24.5.2",
     "chai": "^4.3.10",
     "chai-as-promised": "^7.1.1",
-    "eslint": "^10.4.0",
     "mocha": "^11.1.0",
     "mocha-junit-reporter": "^2.2.1",
     "mocha-multi-reporters": "^1.5.1",

+ 0 - 3
libraries/ranges-tracker/package.json

@@ -17,10 +17,7 @@
     "types:check": "tsc --noEmit"
   },
   "devDependencies": {
-    "@types/node": "^24.5.2",
     "chai": "^4.3.6",
-    "core-js": "~3.46.0",
-    "eslint": "^10.4.0",
     "mocha": "^11.1.0",
     "mocha-junit-reporter": "^2.2.1",
     "mocha-multi-reporters": "^1.5.1",

+ 0 - 2
libraries/redis-wrapper/package.json

@@ -32,9 +32,7 @@
   "devDependencies": {
     "@overleaf/logger": "workspace:*",
     "@overleaf/o-error": "workspace:*",
-    "@types/node": "^24.5.2",
     "chai": "^4.3.6",
-    "eslint": "^10.4.0",
     "mocha": "^11.1.0",
     "mocha-junit-reporter": "^2.2.1",
     "mocha-multi-reporters": "^1.5.1",

+ 2 - 12
libraries/settings/Settings.js

@@ -1,7 +1,6 @@
 /* eslint-disable no-console */
 const fs = require('node:fs')
 const Path = require('node:path')
-const { createRequire } = require('node:module')
 const { merge } = require('./merge')
 
 const CWD = process.cwd()
@@ -17,15 +16,6 @@ if (SHARELATEX_CONFIG && SHARELATEX_CONFIG !== OVERLEAF_CONFIG) {
   )
 }
 
-// Under Yarn PnP, require() resolves dependencies based on the issuer package.
-// Config files live in the consuming service (e.g. web), not in @overleaf/settings,
-// so we create a require function anchored at each config file's location to ensure
-// dependencies resolve from the service's PnP scope rather than this library's.
-function requireFromFile(filePath) {
-  const absPath = Path.resolve(filePath)
-  return createRequire(absPath)(absPath)
-}
-
 let settings
 let settingsExist = false
 const defaultsPath =
@@ -35,7 +25,7 @@ const defaultsPath =
   pathIfExists(Path.join(ENTRY_POINT_DIR, 'config/settings.defaults.js'))
 if (defaultsPath) {
   console.log(`Using default settings from ${defaultsPath}`)
-  settings = requireFromFile(defaultsPath)
+  settings = require(defaultsPath)
   settingsExist = true
 } else {
   settings = {}
@@ -47,7 +37,7 @@ const overridesPath =
   pathIfExists(Path.join(CWD, `config/settings.${NODE_ENV}.js`))
 if (overridesPath) {
   console.log(`Using settings from ${overridesPath}`)
-  settings = merge(requireFromFile(overridesPath), settings)
+  settings = merge(require(overridesPath), settings)
   settingsExist = true
 }
 

+ 0 - 2
libraries/settings/package.json

@@ -13,8 +13,6 @@
     "types:check": "tsc --noEmit"
   },
   "devDependencies": {
-    "@types/node": "^24.5.2",
-    "eslint": "^10.4.0",
     "mocha": "^11.1.0",
     "mocha-junit-reporter": "^2.2.1",
     "mocha-multi-reporters": "^1.5.1",

+ 0 - 2
libraries/stream-utils/package.json

@@ -14,10 +14,8 @@
   "author": "Overleaf (https://www.overleaf.com)",
   "license": "AGPL-3.0-only",
   "devDependencies": {
-    "@types/node": "^24.5.2",
     "chai": "^4.3.6",
     "chai-as-promised": "^7.1.1",
-    "eslint": "^10.4.0",
     "mocha": "^11.1.0",
     "mocha-junit-reporter": "^2.2.1",
     "mocha-multi-reporters": "^1.5.1",

+ 0 - 3
libraries/validation-tools/package.json

@@ -24,9 +24,6 @@
     "zod-validation-error": "^4.0.1"
   },
   "devDependencies": {
-    "@types/express": "4.17.23",
-    "@types/node": "^24.5.2",
-    "eslint": "^10.4.0",
     "typescript": "^5.0.4",
     "vitest": "4.1.5"
   }

+ 1 - 13
package.json

@@ -26,7 +26,6 @@
     "eslint-plugin-promise": "^7.2.1",
     "eslint-plugin-unicorn": "^56.0.0",
     "globals": "^17.6.0",
-    "js-yaml": "^4.1.1",
     "prettier": "3.7.4",
     "prettier-plugin-groovy": "0.2.1",
     "typescript": "^5.9.3"
@@ -132,7 +131,6 @@
     "cache-flow": "1.9.0",
     "focus-trap-react": "11.0.4",
     "jose": "4.15.5",
-    "js-yaml": "^4.1.1",
     "nodemailer": "8.0.5",
     "on-headers": "1.0.2",
     "pug": "3.0.3",
@@ -198,7 +196,6 @@
   },
   "workspaces": [
     "jobs/mirror-documentation",
-    "jobs/wiki-algolia",
     "libraries/*",
     "server-ce/test",
     "services/analytics",
@@ -215,7 +212,6 @@
     "services/history-v1",
     "services/idp",
     "services/latexqc",
-    "services/linked-url-proxy",
     "services/notifications",
     "services/project-history",
     "services/real-time",
@@ -227,13 +223,5 @@
     "tools/npm-overrides-helper",
     "tools/saas-e2e",
     "tools/migrations"
-  ],
-  "dependenciesMeta": {
-    "cypress-multi-reporters@2.0.5": {
-      "unplugged": true
-    },
-    "esmock@2.7.3": {
-      "unplugged": true
-    }
-  }
+  ]
 }

+ 3 - 6
server-ce/Dockerfile

@@ -10,12 +10,13 @@ WORKDIR /overleaf
 
 # Add required source files for yarn install
 # -------------------------------------------
-COPY --parents libraries/*/package.json .yarn/patches/ services/*/package.json tools/migrations/ package.json yarn.lock .yarnrc.yml .pnp.register.mjs /overleaf/
+COPY --parents libraries/*/package.json .yarn/patches/ services/*/package.json tools/migrations/ package.json yarn.lock .yarnrc.yml /overleaf/
 COPY server-ce/genScript.js server-ce/services.js /overleaf/
 
 # Pre-install yarn via corepack so it is available at runtime for all users
 # -------------------------------------------------------------------------
 # Corepack setup, shared between all the images.
+ENV PATH="/overleaf/node_modules/.bin:$PATH"
 ENV COREPACK_HOME=/opt/corepack
 RUN corepack enable && corepack install -g yarn@4.14.1
 ENV COREPACK_ENABLE_NETWORK=0
@@ -33,14 +34,10 @@ COPY --parents libraries/ services/ tools/migrations/ /overleaf/
 RUN --mount=type=cache,target=/root/.cache \
     --mount=type=cache,target=/root/.yarn/berry/cache,id=server-ce-yarn-cache \
     --mount=type=cache,target=/usr/local/share/.cache/yarn,id=server-ce-yarn-fallback-cache \
-    --mount=type=cache,target=/overleaf/services/web/.cache,id=server-ce-webpack-cache \
+    --mount=type=cache,target=/overleaf/services/web/node_modules/.cache,id=server-ce-webpack-cache \
     --mount=type=tmpfs,target=/tmp \
     node genScript compile | bash
 
-# Enable Yarn PnP resolution for all Node.js processes
-# -----------------------------------------------------
-ENV NODE_OPTIONS="--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs"
-
 # Copy runit service startup scripts to its location
 # --------------------------------------------------
 ADD server-ce/runit /etc/service

+ 0 - 1
server-ce/test/.gitignore

@@ -1,3 +1,2 @@
 data/
 docker-mailtrap/
-cypress/reporter/

+ 1 - 0
server-ce/test/Dockerfile

@@ -1,6 +1,7 @@
 FROM node:24.14.1
 
 # Corepack setup, shared between all the images.
+ENV PATH="/overleaf/node_modules/.bin:$PATH"
 ENV COREPACK_HOME=/opt/corepack
 RUN corepack enable && corepack install -g yarn@4.14.1
 ENV COREPACK_ENABLE_NETWORK=0

+ 1 - 4
server-ce/test/cypress.config.ts

@@ -33,13 +33,10 @@ if (process.env.CYPRESS_SHARD && !process.env.SPEC_PATTERN) {
 
 const specPattern = process.env.SPEC_PATTERN || './**/*.spec.ts'
 
-// Cypress's Electron process uses PackherdModuleLoader which doesn't go through
-// PnP hooks. Reporter packages are materialized into /tmp/cypress-reporter by
-// scripts/materialize-cypress-reporter.cjs at container startup.
 let reporterOptions = {}
 if (process.env.CI) {
   reporterOptions = {
-    reporter: '/tmp/cypress-reporter/node_modules/cypress-multi-reporters',
+    reporter: `${process.env.MONOREPO}/node_modules/cypress-multi-reporters`,
     reporterOptions: {
       configFile: 'cypress/cypress-multi-reporters.cjs',
     },

+ 8 - 12
server-ce/test/docker-compose.yml

@@ -79,15 +79,12 @@ services:
     working_dir: $PWD
     volumes:
       - $PWD:$PWD
-      - $MONOREPO/libraries:$MONOREPO/libraries:ro
-      - $MONOREPO/scripts:$MONOREPO/scripts:ro
-      - $MONOREPO/.yarn:$MONOREPO/.yarn:ro
-      - $MONOREPO/.yarnrc.yml:$MONOREPO/.yarnrc.yml:ro
-      - $MONOREPO/.pnp.cjs:$MONOREPO/.pnp.cjs:ro
-      - $MONOREPO/.pnp.loader.mjs:$MONOREPO/.pnp.loader.mjs:ro
-      - $MONOREPO/.pnp.register.mjs:$MONOREPO/.pnp.register.mjs:ro
-      - $MONOREPO/package.json:$MONOREPO/package.json:ro
-      - $MONOREPO/yarn.lock:$MONOREPO/yarn.lock:ro
+      - $MONOREPO/libraries:$MONOREPO/libraries
+      - $MONOREPO/node_modules:$MONOREPO/node_modules
+      - $MONOREPO/.yarn:$MONOREPO/.yarn
+      - $MONOREPO/.yarnrc.yml:$MONOREPO/.yarnrc.yml
+      - $MONOREPO/package.json:$MONOREPO/package.json
+      - $MONOREPO/yarn.lock:$MONOREPO/yarn.lock
     environment:
       MONOREPO:
       CYPRESS_SHARD:
@@ -111,16 +108,15 @@ services:
 
   host-admin:
     build: .
-    entrypoint: ["yarn", "node", "--watch", "host-admin.js"]
+    entrypoint: ["node", "--watch", "host-admin.js"]
     # See comment in Makefile regarding matching file paths
     working_dir: $PWD
     volumes:
       - $PWD:$PWD
       - $MONOREPO/libraries:$MONOREPO/libraries:ro
+      - $MONOREPO/node_modules:$MONOREPO/node_modules:ro
       - $MONOREPO/.yarn:$MONOREPO/.yarn:ro
       - $MONOREPO/.yarnrc.yml:$MONOREPO/.yarnrc.yml:ro
-      - $MONOREPO/.pnp.cjs:$MONOREPO/.pnp.cjs:ro
-      - $MONOREPO/.pnp.loader.mjs:$MONOREPO/.pnp.loader.mjs:ro
       - $MONOREPO/package.json:$MONOREPO/package.json:ro
       - $MONOREPO/yarn.lock:$MONOREPO/yarn.lock:ro
       - /var/run/docker.sock:/var/run/docker.sock

+ 2 - 7
server-ce/test/package.json

@@ -4,9 +4,8 @@
   "private": true,
   "type": "module",
   "scripts": {
-    "materialize-reporter": "node ../../scripts/materialize-cypress-reporter.cjs /tmp/cypress-reporter",
-    "cypress:open": "yarn run materialize-reporter && cypress open --e2e --browser chrome",
-    "cypress:run": "yarn run materialize-reporter && cypress run --e2e --browser chrome",
+    "cypress:open": "cypress open --e2e --browser chrome",
+    "cypress:run": "cypress run --e2e --browser chrome",
     "lint": "eslint --cache --cache-location ../../.cache/eslint/ --max-warnings 0 --format unix --ext .js,.jsx,.mjs,.ts,.tsx .",
     "lint:fix": "eslint --cache --cache-location ../../.cache/eslint/ --fix --ext .js,.jsx,.mjs,.ts,.tsx ."
   },
@@ -21,15 +20,11 @@
     "body-parser": "1.20.4",
     "cypress": "15.12.0",
     "cypress-multi-reporters": "^2.0.5",
-    "eslint": "^10.4.0",
-    "eslint-formatter-unix": "^8.40.0",
     "express": "4.22.1",
     "isomorphic-git": "^1.33.1",
     "js-yaml": "^4.1.1",
-    "mocha": "^11.7.5",
     "mocha-junit-reporter": "^2.2.1",
     "pdfjs-dist": "^5.1.91",
-    "typescript": "^5.0.4",
     "uuid": "^9.0.1",
     "zod-validation-error": "^4.0.1"
   }

+ 2 - 3
services/chat/Dockerfile

@@ -5,6 +5,7 @@
 FROM node:24.14.1 AS base
 
 # Corepack setup, shared between all the images.
+ENV PATH="/overleaf/node_modules/.bin:$PATH"
 ENV COREPACK_HOME=/opt/corepack
 RUN corepack enable && corepack install -g yarn@4.14.1
 ENV COREPACK_ENABLE_NETWORK=0
@@ -17,7 +18,7 @@ RUN mkdir /home/node/.config && chown node:node /home/node/.config
 
 FROM base AS app
 
-COPY package.json yarn.lock .yarnrc.yml .pnp.register.mjs /overleaf/
+COPY package.json yarn.lock .yarnrc.yml /overleaf/
 COPY libraries/eslint-plugin/package.json /overleaf/libraries/eslint-plugin/package.json
 COPY libraries/fetch-utils/package.json /overleaf/libraries/fetch-utils/package.json
 COPY libraries/logger/package.json /overleaf/libraries/logger/package.json
@@ -43,8 +44,6 @@ COPY libraries/settings/ /overleaf/libraries/settings/
 COPY services/chat/ /overleaf/services/chat/
 COPY tools/migrations/ /overleaf/tools/migrations/
 
-ENV NODE_OPTIONS="--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs"
-
 FROM app
 USER node
 

+ 3 - 5
services/chat/Makefile

@@ -69,11 +69,9 @@ clean:
 # Eslint and prettier (plus some configs) are on the root.
 RUN_LINTING = ../../bin/run -w /overleaf/services/$(PROJECT_NAME) monorepo yarn run --silent
 RUN_LINTING_MONOREPO = ../../bin/run monorepo yarn run --silent
-RUN_EXEC_MONOREPO = ../../bin/run monorepo yarn exec
 
 RUN_LINTING_CI = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/chat/reports:/overleaf/services/chat/reports --volume $(MONOREPO)/.cache:/overleaf/.cache $(IMAGE_CI) yarn run --silent
 RUN_LINTING_CI_MONOREPO = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/chat/reports:/overleaf/services/chat/reports --volume $(MONOREPO)/.cache:/overleaf/.cache -w /overleaf $(IMAGE_CI) yarn run --silent
-RUN_EXEC_CI_MONOREPO = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/chat/reports:/overleaf/services/chat/reports --volume $(MONOREPO)/.cache:/overleaf/.cache -w /overleaf $(IMAGE_CI) yarn exec
 
 SHELLCHECK_OPTS = \
 	--shell=bash \
@@ -121,14 +119,14 @@ format_fix:
 	$(RUN_LINTING_MONOREPO) format:fix services/chat
 
 lint:
-	$(RUN_EXEC_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --max-warnings 0 --format unix services/chat
+	$(RUN_LINTING) lint
 
 lint_ci:
-	-$(RUN_EXEC_CI_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --max-warnings 0 --format json --output-file services/chat/reports/eslint.json services/chat
+	-$(RUN_LINTING_CI) lint --format json --output-file reports/eslint.json
 	sed -i 's_"filePath":"/overleaf_"filePath":"$(MONOREPO)_g' reports/eslint.json
 
 lint_fix:
-	$(RUN_EXEC_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --fix services/chat
+	$(RUN_LINTING) lint:fix
 
 typecheck:
 	$(RUN_LINTING) types:check

+ 4 - 8
services/chat/docker-compose.yml

@@ -10,14 +10,12 @@ services:
       target: base
     volumes:
       - .:/overleaf/services/chat
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../package.json:/overleaf/package.json
       - ../../.yarnrc.yml:/overleaf/.yarnrc.yml
       - ../../yarn.lock:/overleaf/yarn.lock
       - ../../.yarn:/overleaf/.yarn
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
       - ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
       - ../../tools/migrations:/overleaf/tools/migrations
     working_dir: /overleaf/services/chat
@@ -26,7 +24,7 @@ services:
       LOG_LEVEL: ${LOG_LEVEL:-}
       MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
       NODE_ENV: test
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs --unhandled-rejections=strict"
+      NODE_OPTIONS: "--unhandled-rejections=strict"
     entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
     command: yarn run --silent test:unit
     user: node
@@ -41,14 +39,12 @@ services:
       target: base
     volumes:
       - .:/overleaf/services/chat
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../package.json:/overleaf/package.json
       - ../../.yarnrc.yml:/overleaf/.yarnrc.yml
       - ../../yarn.lock:/overleaf/yarn.lock
       - ../../.yarn:/overleaf/.yarn
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
       - ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
       - ../../tools/migrations:/overleaf/tools/migrations
     working_dir: /overleaf/services/chat
@@ -59,7 +55,7 @@ services:
       MOCHA_GREP: ${MOCHA_GREP}
       LOG_LEVEL: ${LOG_LEVEL:-}
       NODE_ENV: test
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs --unhandled-rejections=strict"
+      NODE_OPTIONS: "--unhandled-rejections=strict"
     user: node
     depends_on:
       mongo:

+ 0 - 2
services/chat/package.json

@@ -29,12 +29,10 @@
   },
   "devDependencies": {
     "@overleaf/migrations": "workspace:*",
-    "@types/node": "^24.5.2",
     "acorn": "^7.1.1",
     "ajv": "^6.12.0",
     "chai": "^4.3.6",
     "chai-as-promised": "^7.1.1",
-    "eslint": "^10.4.0",
     "mocha": "^11.1.0",
     "mocha-junit-reporter": "^2.2.1",
     "mocha-multi-reporters": "^1.5.1",

+ 1 - 1
services/chat/test/acceptance/js/helpers/MongoHelper.js

@@ -5,6 +5,6 @@ before('run migrations', async function () {
   this.timeout(60_000)
 
   await promisify(exec)(
-    `cd ../../tools/migrations && yarn run migrations migrate -t server-ce`
+    `cd ../../tools/migrations && npm run migrations -- migrate -t server-ce`
   )
 })

+ 7 - 8
services/clsi/Dockerfile

@@ -5,6 +5,7 @@
 FROM node:24.14.1 AS base
 
 # Corepack setup, shared between all the images.
+ENV PATH="/overleaf/node_modules/.bin:$PATH"
 ENV COREPACK_HOME=/opt/corepack
 RUN corepack enable && corepack install -g yarn@4.14.1
 ENV COREPACK_ENABLE_NETWORK=0
@@ -21,7 +22,7 @@ RUN mkdir /home/node/.config && chown node:node /home/node/.config
 
 FROM base AS app
 
-COPY package.json yarn.lock .yarnrc.yml .pnp.register.mjs /overleaf/
+COPY package.json yarn.lock .yarnrc.yml /overleaf/
 COPY libraries/eslint-plugin/package.json /overleaf/libraries/eslint-plugin/package.json
 COPY libraries/fetch-utils/package.json /overleaf/libraries/fetch-utils/package.json
 COPY libraries/logger/package.json /overleaf/libraries/logger/package.json
@@ -48,22 +49,20 @@ COPY libraries/stream-utils/ /overleaf/libraries/stream-utils/
 COPY libraries/validation-tools/ /overleaf/libraries/validation-tools/
 COPY services/clsi/ /overleaf/services/clsi/
 
-ENV NODE_OPTIONS="--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs"
-
 FROM app AS with-texlive
 
 RUN apt-get update \
-  && apt-cache depends texlive-full | grep "Depends: " | grep -v -- "-doc" | grep -v -- "-lang-" | sed 's/Depends: //' | xargs apt-get install -y --no-install-recommends \
-  && apt-get install -y --no-install-recommends fontconfig inkscape python3-pygments qpdf \
-  && rm -rf /var/lib/apt/lists/*
+    && apt-cache depends texlive-full | grep "Depends: " | grep -v -- "-doc" | grep -v -- "-lang-" | sed 's/Depends: //' | xargs apt-get install -y --no-install-recommends \
+    && apt-get install -y --no-install-recommends fontconfig inkscape python3-pygments qpdf \
+    && rm -rf /var/lib/apt/lists/*
 
 RUN mkdir -p cache compiles output \
-  &&  chown node:node cache compiles output
+&&  chown node:node cache compiles output
 
 CMD ["node", "--expose-gc", "app.js"]
 
 FROM app
 RUN mkdir -p cache compiles output \
-  &&  chown node:node cache compiles output
+&&  chown node:node cache compiles output
 
 CMD ["node", "--expose-gc", "app.js"]

+ 3 - 5
services/clsi/Makefile

@@ -71,11 +71,9 @@ clean:
 # Eslint and prettier (plus some configs) are on the root.
 RUN_LINTING = ../../bin/run -w /overleaf/services/$(PROJECT_NAME) monorepo yarn run --silent
 RUN_LINTING_MONOREPO = ../../bin/run monorepo yarn run --silent
-RUN_EXEC_MONOREPO = ../../bin/run monorepo yarn exec
 
 RUN_LINTING_CI = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/clsi/reports:/overleaf/services/clsi/reports --volume $(MONOREPO)/.cache:/overleaf/.cache $(IMAGE_CI) yarn run --silent
 RUN_LINTING_CI_MONOREPO = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/clsi/reports:/overleaf/services/clsi/reports --volume $(MONOREPO)/.cache:/overleaf/.cache -w /overleaf $(IMAGE_CI) yarn run --silent
-RUN_EXEC_CI_MONOREPO = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/clsi/reports:/overleaf/services/clsi/reports --volume $(MONOREPO)/.cache:/overleaf/.cache -w /overleaf $(IMAGE_CI) yarn exec
 
 SHELLCHECK_OPTS = \
 	--shell=bash \
@@ -123,14 +121,14 @@ format_fix:
 	$(RUN_LINTING_MONOREPO) format:fix services/clsi
 
 lint:
-	$(RUN_EXEC_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --max-warnings 0 --format unix services/clsi
+	$(RUN_LINTING) lint
 
 lint_ci:
-	-$(RUN_EXEC_CI_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --max-warnings 0 --format json --output-file services/clsi/reports/eslint.json services/clsi
+	-$(RUN_LINTING_CI) lint --format json --output-file reports/eslint.json
 	sed -i 's_"filePath":"/overleaf_"filePath":"$(MONOREPO)_g' reports/eslint.json
 
 lint_fix:
-	$(RUN_EXEC_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --fix services/clsi
+	$(RUN_LINTING) lint:fix
 
 typecheck:
 	$(RUN_LINTING) types:check

+ 4 - 8
services/clsi/docker-compose.yml

@@ -10,14 +10,12 @@ services:
       target: base
     volumes:
       - .:/overleaf/services/clsi
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../package.json:/overleaf/package.json
       - ../../.yarnrc.yml:/overleaf/.yarnrc.yml
       - ../../yarn.lock:/overleaf/yarn.lock
       - ../../.yarn:/overleaf/.yarn
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
       - ../../tsconfig.backend.json:/overleaf/tsconfig.backend.json
     working_dir: /overleaf/services/clsi
     environment:
@@ -25,7 +23,7 @@ services:
       LOG_LEVEL: ${LOG_LEVEL:-}
       MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
       NODE_ENV: test
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs --unhandled-rejections=strict"
+      NODE_OPTIONS: "--unhandled-rejections=strict"
     command: yarn run --silent test:unit
 
   test_acceptance:
@@ -35,14 +33,12 @@ services:
       target: base
     volumes:
       - .:/overleaf/services/clsi
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../package.json:/overleaf/package.json
       - ../../.yarnrc.yml:/overleaf/.yarnrc.yml
       - ../../yarn.lock:/overleaf/yarn.lock
       - ../../.yarn:/overleaf/.yarn
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
       - /var/run/docker.sock:/var/run/docker.sock
     working_dir: /overleaf/services/clsi
     environment:
@@ -52,7 +48,7 @@ services:
       MOCHA_GREP: ${MOCHA_GREP}
       LOG_LEVEL: ${LOG_LEVEL:-}
       NODE_ENV: test
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs --unhandled-rejections=strict"
+      NODE_OPTIONS: "--unhandled-rejections=strict"
       DOWNLOAD_HOST: http://clsi-nginx:8080
       ALLOWED_COMPILE_GROUPS: clsi-perf simple-latex-file
       ENABLE_PDF_CACHING: true

+ 0 - 2
services/clsi/package.json

@@ -41,10 +41,8 @@
   },
   "devDependencies": {
     "@istanbuljs/esm-loader-hook": "^0.3.0",
-    "@types/node": "^24.5.2",
     "chai": "^4.3.6",
     "chai-as-promised": "^7.1.1",
-    "eslint": "^10.4.0",
     "form-data": "^4.0.5",
     "mocha": "^11.1.0",
     "mocha-junit-reporter": "^2.2.1",

+ 2 - 3
services/docstore/Dockerfile

@@ -5,6 +5,7 @@
 FROM node:24.14.1 AS base
 
 # Corepack setup, shared between all the images.
+ENV PATH="/overleaf/node_modules/.bin:$PATH"
 ENV COREPACK_HOME=/opt/corepack
 RUN corepack enable && corepack install -g yarn@4.14.1
 ENV COREPACK_ENABLE_NETWORK=0
@@ -17,7 +18,7 @@ RUN mkdir /home/node/.config && chown node:node /home/node/.config
 
 FROM base AS app
 
-COPY package.json yarn.lock .yarnrc.yml .pnp.register.mjs /overleaf/
+COPY package.json yarn.lock .yarnrc.yml /overleaf/
 COPY libraries/eslint-plugin/package.json /overleaf/libraries/eslint-plugin/package.json
 COPY libraries/fetch-utils/package.json /overleaf/libraries/fetch-utils/package.json
 COPY libraries/logger/package.json /overleaf/libraries/logger/package.json
@@ -49,8 +50,6 @@ COPY libraries/validation-tools/ /overleaf/libraries/validation-tools/
 COPY services/docstore/ /overleaf/services/docstore/
 COPY tools/migrations/ /overleaf/tools/migrations/
 
-ENV NODE_OPTIONS="--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs"
-
 FROM app
 USER node
 

+ 3 - 5
services/docstore/Makefile

@@ -72,11 +72,9 @@ clean:
 # Eslint and prettier (plus some configs) are on the root.
 RUN_LINTING = ../../bin/run -w /overleaf/services/$(PROJECT_NAME) monorepo yarn run --silent
 RUN_LINTING_MONOREPO = ../../bin/run monorepo yarn run --silent
-RUN_EXEC_MONOREPO = ../../bin/run monorepo yarn exec
 
 RUN_LINTING_CI = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/docstore/reports:/overleaf/services/docstore/reports --volume $(MONOREPO)/.cache:/overleaf/.cache $(IMAGE_CI) yarn run --silent
 RUN_LINTING_CI_MONOREPO = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/docstore/reports:/overleaf/services/docstore/reports --volume $(MONOREPO)/.cache:/overleaf/.cache -w /overleaf $(IMAGE_CI) yarn run --silent
-RUN_EXEC_CI_MONOREPO = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/docstore/reports:/overleaf/services/docstore/reports --volume $(MONOREPO)/.cache:/overleaf/.cache -w /overleaf $(IMAGE_CI) yarn exec
 
 SHELLCHECK_OPTS = \
 	--shell=bash \
@@ -124,14 +122,14 @@ format_fix:
 	$(RUN_LINTING_MONOREPO) format:fix services/docstore
 
 lint:
-	$(RUN_EXEC_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --max-warnings 0 --format unix services/docstore
+	$(RUN_LINTING) lint
 
 lint_ci:
-	-$(RUN_EXEC_CI_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --max-warnings 0 --format json --output-file services/docstore/reports/eslint.json services/docstore
+	-$(RUN_LINTING_CI) lint --format json --output-file reports/eslint.json
 	sed -i 's_"filePath":"/overleaf_"filePath":"$(MONOREPO)_g' reports/eslint.json
 
 lint_fix:
-	$(RUN_EXEC_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --fix services/docstore
+	$(RUN_LINTING) lint:fix
 
 typecheck:
 	$(RUN_LINTING) types:check

+ 4 - 8
services/docstore/docker-compose.yml

@@ -10,14 +10,12 @@ services:
       target: base
     volumes:
       - .:/overleaf/services/docstore
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../package.json:/overleaf/package.json
       - ../../.yarnrc.yml:/overleaf/.yarnrc.yml
       - ../../yarn.lock:/overleaf/yarn.lock
       - ../../.yarn:/overleaf/.yarn
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
       - ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
       - ../../tools/migrations:/overleaf/tools/migrations
       - ../../tsconfig.backend.json:/overleaf/tsconfig.backend.json
@@ -27,7 +25,7 @@ services:
       LOG_LEVEL: ${LOG_LEVEL:-}
       MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
       NODE_ENV: test
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs --unhandled-rejections=strict"
+      NODE_OPTIONS: "--unhandled-rejections=strict"
     entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
     command: yarn run --silent test:unit
     user: node
@@ -42,14 +40,12 @@ services:
       target: base
     volumes:
       - .:/overleaf/services/docstore
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../package.json:/overleaf/package.json
       - ../../.yarnrc.yml:/overleaf/.yarnrc.yml
       - ../../yarn.lock:/overleaf/yarn.lock
       - ../../.yarn:/overleaf/.yarn
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
       - ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
       - ../../tools/migrations:/overleaf/tools/migrations
     working_dir: /overleaf/services/docstore
@@ -63,7 +59,7 @@ services:
       MOCHA_GREP: ${MOCHA_GREP}
       LOG_LEVEL: ${LOG_LEVEL:-}
       NODE_ENV: test
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs --unhandled-rejections=strict"
+      NODE_OPTIONS: "--unhandled-rejections=strict"
     user: node
     depends_on:
       mongo:

+ 0 - 3
services/docstore/package.json

@@ -31,17 +31,14 @@
     "bunyan": "^1.8.15",
     "express": "4.22.1",
     "lodash": "^4.18.1",
-    "mongodb": "6.12.0",
     "mongodb-legacy": "6.1.3",
     "p-map": "^4.0.0"
   },
   "devDependencies": {
     "@google-cloud/storage": "^7.19.0",
     "@overleaf/migrations": "workspace:*",
-    "@types/node": "^24.5.2",
     "chai": "^4.3.6",
     "chai-as-promised": "^7.1.1",
-    "eslint": "^10.4.0",
     "mocha": "^11.1.0",
     "mocha-junit-reporter": "^2.2.1",
     "mocha-multi-reporters": "^1.5.1",

+ 1 - 1
services/docstore/test/acceptance/js/helpers/MongoHelper.js

@@ -5,6 +5,6 @@ before('run migrations', async function () {
   this.timeout(60_000)
 
   await promisify(exec)(
-    `cd ../../tools/migrations && yarn run migrations migrate -t server-ce`
+    `cd ../../tools/migrations && npm run migrations -- migrate -t server-ce`
   )
 })

+ 2 - 3
services/document-updater/Dockerfile

@@ -5,6 +5,7 @@
 FROM node:24.14.1 AS base
 
 # Corepack setup, shared between all the images.
+ENV PATH="/overleaf/node_modules/.bin:$PATH"
 ENV COREPACK_HOME=/opt/corepack
 RUN corepack enable && corepack install -g yarn@4.14.1
 ENV COREPACK_ENABLE_NETWORK=0
@@ -17,7 +18,7 @@ RUN mkdir /home/node/.config && chown node:node /home/node/.config
 
 FROM base AS app
 
-COPY package.json yarn.lock .yarnrc.yml .pnp.register.mjs /overleaf/
+COPY package.json yarn.lock .yarnrc.yml /overleaf/
 COPY libraries/eslint-plugin/package.json /overleaf/libraries/eslint-plugin/package.json
 COPY libraries/fetch-utils/package.json /overleaf/libraries/fetch-utils/package.json
 COPY libraries/logger/package.json /overleaf/libraries/logger/package.json
@@ -49,8 +50,6 @@ COPY libraries/settings/ /overleaf/libraries/settings/
 COPY services/document-updater/ /overleaf/services/document-updater/
 COPY tools/migrations/ /overleaf/tools/migrations/
 
-ENV NODE_OPTIONS="--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs"
-
 FROM app
 USER node
 

+ 3 - 5
services/document-updater/Makefile

@@ -72,11 +72,9 @@ clean:
 # Eslint and prettier (plus some configs) are on the root.
 RUN_LINTING = ../../bin/run -w /overleaf/services/$(PROJECT_NAME) monorepo yarn run --silent
 RUN_LINTING_MONOREPO = ../../bin/run monorepo yarn run --silent
-RUN_EXEC_MONOREPO = ../../bin/run monorepo yarn exec
 
 RUN_LINTING_CI = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/document-updater/reports:/overleaf/services/document-updater/reports --volume $(MONOREPO)/.cache:/overleaf/.cache $(IMAGE_CI) yarn run --silent
 RUN_LINTING_CI_MONOREPO = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/document-updater/reports:/overleaf/services/document-updater/reports --volume $(MONOREPO)/.cache:/overleaf/.cache -w /overleaf $(IMAGE_CI) yarn run --silent
-RUN_EXEC_CI_MONOREPO = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/document-updater/reports:/overleaf/services/document-updater/reports --volume $(MONOREPO)/.cache:/overleaf/.cache -w /overleaf $(IMAGE_CI) yarn exec
 
 SHELLCHECK_OPTS = \
 	--shell=bash \
@@ -124,14 +122,14 @@ format_fix:
 	$(RUN_LINTING_MONOREPO) format:fix services/document-updater
 
 lint:
-	$(RUN_EXEC_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --max-warnings 0 --format unix services/document-updater
+	$(RUN_LINTING) lint
 
 lint_ci:
-	-$(RUN_EXEC_CI_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --max-warnings 0 --format json --output-file services/document-updater/reports/eslint.json services/document-updater
+	-$(RUN_LINTING_CI) lint --format json --output-file reports/eslint.json
 	sed -i 's_"filePath":"/overleaf_"filePath":"$(MONOREPO)_g' reports/eslint.json
 
 lint_fix:
-	$(RUN_EXEC_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --fix services/document-updater
+	$(RUN_LINTING) lint:fix
 
 typecheck:
 	$(RUN_LINTING) types:check

+ 4 - 8
services/document-updater/docker-compose.yml

@@ -10,14 +10,12 @@ services:
       target: base
     volumes:
       - .:/overleaf/services/document-updater
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../package.json:/overleaf/package.json
       - ../../.yarnrc.yml:/overleaf/.yarnrc.yml
       - ../../yarn.lock:/overleaf/yarn.lock
       - ../../.yarn:/overleaf/.yarn
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
       - ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
       - ../../tools/migrations:/overleaf/tools/migrations
     working_dir: /overleaf/services/document-updater
@@ -26,7 +24,7 @@ services:
       LOG_LEVEL: ${LOG_LEVEL:-}
       MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
       NODE_ENV: test
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs --unhandled-rejections=strict"
+      NODE_OPTIONS: "--unhandled-rejections=strict"
       REDIS_HOST: redis_test
       HISTORY_REDIS_HOST: redis_test
       QUEUES_REDIS_HOST: redis_test
@@ -48,14 +46,12 @@ services:
       target: base
     volumes:
       - .:/overleaf/services/document-updater
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../package.json:/overleaf/package.json
       - ../../.yarnrc.yml:/overleaf/.yarnrc.yml
       - ../../yarn.lock:/overleaf/yarn.lock
       - ../../.yarn:/overleaf/.yarn
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
       - ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
       - ../../tools/migrations:/overleaf/tools/migrations
     working_dir: /overleaf/services/document-updater
@@ -71,7 +67,7 @@ services:
       MOCHA_GREP: ${MOCHA_GREP}
       LOG_LEVEL: ${LOG_LEVEL:-}
       NODE_ENV: test
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs --unhandled-rejections=strict"
+      NODE_OPTIONS: "--unhandled-rejections=strict"
     user: node
     depends_on:
       mongo:

+ 0 - 5
services/document-updater/package.json

@@ -34,20 +34,15 @@
     "express": "4.22.1",
     "lodash": "^4.18.1",
     "minimist": "^1.2.8",
-    "mongodb": "6.12.0",
     "mongodb-legacy": "6.1.3",
     "overleaf-editor-core": "workspace:*"
   },
   "devDependencies": {
     "@overleaf/migrations": "workspace:*",
-    "@types/ioredis": "^4.28.10",
-    "@types/mocha": "^10.0.6",
-    "@types/node": "^24.5.2",
     "basic-auth": "^2.0.1",
     "chai": "^4.3.6",
     "chai-as-promised": "^7.1.1",
     "cluster-key-slot": "^1.0.5",
-    "eslint": "^10.4.0",
     "mocha": "^11.1.0",
     "mocha-junit-reporter": "^2.2.1",
     "mocha-multi-reporters": "^1.5.1",

+ 1 - 4
services/document-updater/scripts/flush_projects_with_no_history_id.js

@@ -204,10 +204,7 @@ async function scanNodes(nodes, batchSize = 1000) {
       }
     }
 
-    logger.info(
-      { scanned, server: /** @type {any} */ (node).serverInfo.role },
-      'Scanned node'
-    )
+    logger.info({ scanned, server: node.serverInfo.role }, 'Scanned node')
   }
 }
 

+ 1 - 1
services/document-updater/test/acceptance/js/helpers/MongoHelper.js

@@ -5,6 +5,6 @@ before('run migrations', async function () {
   this.timeout(60_000)
 
   await promisify(exec)(
-    `cd ../../tools/migrations && yarn run migrations migrate -t server-ce`
+    `cd ../../tools/migrations && npm run migrations -- migrate -t server-ce`
   )
 })

+ 3 - 4
services/filestore/Dockerfile

@@ -5,6 +5,7 @@
 FROM node:24.14.1 AS base
 
 # Corepack setup, shared between all the images.
+ENV PATH="/overleaf/node_modules/.bin:$PATH"
 ENV COREPACK_HOME=/opt/corepack
 RUN corepack enable && corepack install -g yarn@4.14.1
 ENV COREPACK_ENABLE_NETWORK=0
@@ -19,7 +20,7 @@ RUN mkdir /home/node/.config && chown node:node /home/node/.config
 
 FROM base AS app
 
-COPY package.json yarn.lock .yarnrc.yml .pnp.register.mjs /overleaf/
+COPY package.json yarn.lock .yarnrc.yml /overleaf/
 COPY libraries/eslint-plugin/package.json /overleaf/libraries/eslint-plugin/package.json
 COPY libraries/fetch-utils/package.json /overleaf/libraries/fetch-utils/package.json
 COPY libraries/logger/package.json /overleaf/libraries/logger/package.json
@@ -42,11 +43,9 @@ COPY libraries/settings/ /overleaf/libraries/settings/
 COPY libraries/stream-utils/ /overleaf/libraries/stream-utils/
 COPY services/filestore/ /overleaf/services/filestore/
 
-ENV NODE_OPTIONS="--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs"
-
 FROM app
 RUN mkdir -p uploads template_files \
-  &&  chown node:node uploads template_files
+&&  chown node:node uploads template_files
 USER node
 
 CMD ["node", "--expose-gc", "app.js"]

+ 3 - 5
services/filestore/Makefile

@@ -69,11 +69,9 @@ clean:
 # Eslint and prettier (plus some configs) are on the root.
 RUN_LINTING = ../../bin/run -w /overleaf/services/$(PROJECT_NAME) monorepo yarn run --silent
 RUN_LINTING_MONOREPO = ../../bin/run monorepo yarn run --silent
-RUN_EXEC_MONOREPO = ../../bin/run monorepo yarn exec
 
 RUN_LINTING_CI = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/filestore/reports:/overleaf/services/filestore/reports --volume $(MONOREPO)/.cache:/overleaf/.cache $(IMAGE_CI) yarn run --silent
 RUN_LINTING_CI_MONOREPO = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/filestore/reports:/overleaf/services/filestore/reports --volume $(MONOREPO)/.cache:/overleaf/.cache -w /overleaf $(IMAGE_CI) yarn run --silent
-RUN_EXEC_CI_MONOREPO = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/filestore/reports:/overleaf/services/filestore/reports --volume $(MONOREPO)/.cache:/overleaf/.cache -w /overleaf $(IMAGE_CI) yarn exec
 
 SHELLCHECK_OPTS = \
 	--shell=bash \
@@ -121,14 +119,14 @@ format_fix:
 	$(RUN_LINTING_MONOREPO) format:fix services/filestore
 
 lint:
-	$(RUN_EXEC_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --max-warnings 0 --format unix services/filestore
+	$(RUN_LINTING) lint
 
 lint_ci:
-	-$(RUN_EXEC_CI_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --max-warnings 0 --format json --output-file services/filestore/reports/eslint.json services/filestore
+	-$(RUN_LINTING_CI) lint --format json --output-file reports/eslint.json
 	sed -i 's_"filePath":"/overleaf_"filePath":"$(MONOREPO)_g' reports/eslint.json
 
 lint_fix:
-	$(RUN_EXEC_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --fix services/filestore
+	$(RUN_LINTING) lint:fix
 
 typecheck:
 	$(RUN_LINTING) types:check

+ 4 - 8
services/filestore/docker-compose.yml

@@ -13,14 +13,12 @@ services:
       target: base
     volumes:
       - .:/overleaf/services/filestore
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../package.json:/overleaf/package.json
       - ../../.yarnrc.yml:/overleaf/.yarnrc.yml
       - ../../yarn.lock:/overleaf/yarn.lock
       - ../../.yarn:/overleaf/.yarn
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
       - ../../tsconfig.backend.json:/overleaf/tsconfig.backend.json
     working_dir: /overleaf/services/filestore
     environment:
@@ -28,7 +26,7 @@ services:
       LOG_LEVEL: ${LOG_LEVEL:-}
       MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
       NODE_ENV: test
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs --unhandled-rejections=strict"
+      NODE_OPTIONS: "--unhandled-rejections=strict"
     command: yarn run --silent test:unit
     user: node
 
@@ -39,14 +37,12 @@ services:
       target: base
     volumes:
       - .:/overleaf/services/filestore
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../package.json:/overleaf/package.json
       - ../../.yarnrc.yml:/overleaf/.yarnrc.yml
       - ../../yarn.lock:/overleaf/yarn.lock
       - ../../.yarn:/overleaf/.yarn
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
       - minio-certs:/certs
     working_dir: /overleaf/services/filestore
     environment:
@@ -66,7 +62,7 @@ services:
       MOCHA_GREP: ${MOCHA_GREP}
       LOG_LEVEL: ${LOG_LEVEL:-}
       NODE_ENV: test
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs --unhandled-rejections=strict"
+      NODE_OPTIONS: "--unhandled-rejections=strict"
       ENABLE_CONVERSIONS: true
       USE_PROM_METRICS: true
       AWS_S3_USER_FILES_STORAGE_CLASS: REDUCED_REDUNDANCY

+ 0 - 2
services/filestore/package.json

@@ -36,10 +36,8 @@
   },
   "devDependencies": {
     "@google-cloud/storage": "^7.19.0",
-    "@types/node": "^24.5.2",
     "chai": "^4.3.6",
     "chai-as-promised": "^7.1.1",
-    "eslint": "^10.4.0",
     "mocha": "^11.1.0",
     "mocha-junit-reporter": "^2.2.1",
     "mocha-multi-reporters": "^1.5.1",

+ 2 - 3
services/history-v1/Dockerfile

@@ -5,6 +5,7 @@
 FROM node:24.14.1 AS base
 
 # Corepack setup, shared between all the images.
+ENV PATH="/overleaf/node_modules/.bin:$PATH"
 ENV COREPACK_HOME=/opt/corepack
 RUN corepack enable && corepack install -g yarn@4.14.1
 ENV COREPACK_ENABLE_NETWORK=0
@@ -22,7 +23,7 @@ RUN mkdir /buckets && chown node:node /buckets
 
 FROM base AS app
 
-COPY package.json yarn.lock .yarnrc.yml .pnp.register.mjs /overleaf/
+COPY package.json yarn.lock .yarnrc.yml /overleaf/
 COPY libraries/eslint-plugin/package.json /overleaf/libraries/eslint-plugin/package.json
 COPY libraries/fetch-utils/package.json /overleaf/libraries/fetch-utils/package.json
 COPY libraries/logger/package.json /overleaf/libraries/logger/package.json
@@ -58,8 +59,6 @@ COPY libraries/validation-tools/ /overleaf/libraries/validation-tools/
 COPY services/history-v1/ /overleaf/services/history-v1/
 COPY tools/migrations/ /overleaf/tools/migrations/
 
-ENV NODE_OPTIONS="--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs"
-
 FROM app
 USER node
 

+ 3 - 5
services/history-v1/Makefile

@@ -74,11 +74,9 @@ clean:
 # Eslint and prettier (plus some configs) are on the root.
 RUN_LINTING = ../../bin/run -w /overleaf/services/$(PROJECT_NAME) monorepo yarn run --silent
 RUN_LINTING_MONOREPO = ../../bin/run monorepo yarn run --silent
-RUN_EXEC_MONOREPO = ../../bin/run monorepo yarn exec
 
 RUN_LINTING_CI = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/history-v1/reports:/overleaf/services/history-v1/reports --volume $(MONOREPO)/.cache:/overleaf/.cache $(IMAGE_CI) yarn run --silent
 RUN_LINTING_CI_MONOREPO = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/history-v1/reports:/overleaf/services/history-v1/reports --volume $(MONOREPO)/.cache:/overleaf/.cache -w /overleaf $(IMAGE_CI) yarn run --silent
-RUN_EXEC_CI_MONOREPO = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/history-v1/reports:/overleaf/services/history-v1/reports --volume $(MONOREPO)/.cache:/overleaf/.cache -w /overleaf $(IMAGE_CI) yarn exec
 
 SHELLCHECK_OPTS = \
 	--shell=bash \
@@ -126,14 +124,14 @@ format_fix:
 	$(RUN_LINTING_MONOREPO) format:fix services/history-v1
 
 lint:
-	$(RUN_EXEC_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --max-warnings 0 --format unix services/history-v1
+	$(RUN_LINTING) lint
 
 lint_ci:
-	-$(RUN_EXEC_CI_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --max-warnings 0 --format json --output-file services/history-v1/reports/eslint.json services/history-v1
+	-$(RUN_LINTING_CI) lint --format json --output-file reports/eslint.json
 	sed -i 's_"filePath":"/overleaf_"filePath":"$(MONOREPO)_g' reports/eslint.json
 
 lint_fix:
-	$(RUN_EXEC_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --fix services/history-v1
+	$(RUN_LINTING) lint:fix
 
 typecheck:
 	$(RUN_LINTING) types:check

+ 4 - 8
services/history-v1/docker-compose.yml

@@ -13,14 +13,12 @@ services:
       target: base
     volumes:
       - .:/overleaf/services/history-v1
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../package.json:/overleaf/package.json
       - ../../.yarnrc.yml:/overleaf/.yarnrc.yml
       - ../../yarn.lock:/overleaf/yarn.lock
       - ../../.yarn:/overleaf/.yarn
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
       - ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
       - ../../tools/migrations:/overleaf/tools/migrations
     working_dir: /overleaf/services/history-v1
@@ -29,7 +27,7 @@ services:
       LOG_LEVEL: ${LOG_LEVEL:-}
       MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
       NODE_ENV: test
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs --unhandled-rejections=strict"
+      NODE_OPTIONS: "--unhandled-rejections=strict"
       REDIS_HOST: redis_test
       HISTORY_REDIS_HOST: redis_test
       QUEUES_REDIS_HOST: redis_test
@@ -51,14 +49,12 @@ services:
       target: base
     volumes:
       - .:/overleaf/services/history-v1
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../package.json:/overleaf/package.json
       - ../../.yarnrc.yml:/overleaf/.yarnrc.yml
       - ../../yarn.lock:/overleaf/yarn.lock
       - ../../.yarn:/overleaf/.yarn
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
       - minio-certs:/certs
       - ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
       - ../../tools/migrations:/overleaf/tools/migrations
@@ -85,7 +81,7 @@ services:
       MOCHA_GREP: ${MOCHA_GREP}
       LOG_LEVEL: ${LOG_LEVEL:-}
       NODE_ENV: test
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs --unhandled-rejections=strict"
+      NODE_OPTIONS: "--unhandled-rejections=strict"
     user: node
     depends_on:
       mongo:

+ 0 - 6
services/history-v1/package.json

@@ -7,7 +7,6 @@
   "private": true,
   "dependencies": {
     "@google-cloud/secret-manager": "^5.6.0",
-    "@google-cloud/storage": "^7.19.0",
     "@overleaf/fetch-utils": "workspace:*",
     "@overleaf/logger": "workspace:*",
     "@overleaf/metrics": "workspace:*",
@@ -49,16 +48,11 @@
     "zip-stream": "^7.0.2"
   },
   "devDependencies": {
-    "@aws-sdk/client-s3": "^3.994.0",
     "@overleaf/migrations": "workspace:*",
-    "@types/chai-as-promised": "^7.1.8",
-    "@types/mocha": "^10.0.6",
-    "@types/node": "^24.5.2",
     "benny": "^3.7.1",
     "chai": "^4.3.6",
     "chai-as-promised": "^7.1.1",
     "chai-exclude": "^2.1.1",
-    "eslint": "^10.4.0",
     "mocha": "^11.1.0",
     "mocha-junit-reporter": "^2.2.1",
     "mocha-multi-reporters": "^1.5.1",

+ 2 - 3
services/history-v1/storage/scripts/back_fill_file_hash.mjs

@@ -316,9 +316,8 @@ if (OUTPUT_FILE !== '-') {
 logger.initialize('file-migration', {
   streams: [
     {
-      stream: DISPLAY_REPORT
-        ? process.stderr
-        : OUTPUT_FILE === '-'
+      stream:
+        OUTPUT_FILE === '-'
           ? process.stdout
           : fs.createWriteStream(OUTPUT_FILE, { flags: 'a' }),
     },

+ 1 - 3
services/history-v1/storage/scripts/fix_string_backedUpBlobs_ids.mjs

@@ -1,11 +1,9 @@
 // @ts-check
 import { backedUpBlobs } from '../lib/mongodb.js'
-import assert from '../lib/assert.js'
+import { mongoId } from '../lib/assert.js'
 import { ObjectId } from 'mongodb'
 import commandLineArgs from 'command-line-args'
 
-const { mongoId } = assert
-
 const STATS = {
   total: 0,
   replaced: 0,

+ 2 - 3
services/history-v1/test/acceptance/js/storage/back_fill_file_hash.test.mjs

@@ -485,7 +485,7 @@ describe('back_fill_file_hash script', function () {
    * @param {Array<string>} args
    * @return {Promise<{result: { stdout: string, stderr: string, status: number }, stats: any}>}
    */
-  async function rawRunScript(args = [], env = {}) {
+  async function rawRunScript(args = []) {
     let result
     try {
       result = await promisify(execFile)(
@@ -502,7 +502,6 @@ describe('back_fill_file_hash script', function () {
             ...process.env,
             AWS_SDK_JS_SUPPRESS_MAINTENANCE_MODE_MESSAGE: '1',
             LOG_LEVEL: 'warn', // Override LOG_LEVEL of acceptance tests
-            ...env,
           },
         }
       )
@@ -1121,7 +1120,7 @@ describe('back_fill_file_hash script', function () {
     let output
     before('prepare environment', prepareEnvironment)
     before('run script', async function () {
-      output = await rawRunScript(['--report'], { LOG_LEVEL: 'error' })
+      output = await rawRunScript(['--report'])
     })
     it('should print the report', () => {
       expect(output.status).to.equal(0)

+ 1 - 1
services/history-v1/test/acceptance/js/storage/recover_zip.test.mjs

@@ -140,7 +140,7 @@ async function runRecoverZipScript(args) {
   try {
     result = await promisify(execFile)(
       'node',
-      ['--no-deprecation', 'storage/scripts/recover_zip.js', ...args],
+      ['storage/scripts/recover_zip.js', ...args],
       {
         encoding: 'utf-8',
         timeout: TIMEOUT,

+ 1 - 1
services/history-v1/test/setup.js

@@ -22,7 +22,7 @@ async function setupMongoDatabase() {
   this.timeout(60_000)
   await promisify(exec)(
     // Run saas migrations for backup indexes
-    `cd ../../tools/migrations && yarn run migrations migrate -t saas`
+    `cd ../../tools/migrations && npm run migrations -- migrate -t saas`
   )
 }
 

+ 2 - 3
services/notifications/Dockerfile

@@ -5,6 +5,7 @@
 FROM node:24.14.1 AS base
 
 # Corepack setup, shared between all the images.
+ENV PATH="/overleaf/node_modules/.bin:$PATH"
 ENV COREPACK_HOME=/opt/corepack
 RUN corepack enable && corepack install -g yarn@4.14.1
 ENV COREPACK_ENABLE_NETWORK=0
@@ -17,7 +18,7 @@ RUN mkdir /home/node/.config && chown node:node /home/node/.config
 
 FROM base AS app
 
-COPY package.json yarn.lock .yarnrc.yml .pnp.register.mjs /overleaf/
+COPY package.json yarn.lock .yarnrc.yml /overleaf/
 COPY libraries/eslint-plugin/package.json /overleaf/libraries/eslint-plugin/package.json
 COPY libraries/fetch-utils/package.json /overleaf/libraries/fetch-utils/package.json
 COPY libraries/logger/package.json /overleaf/libraries/logger/package.json
@@ -45,8 +46,6 @@ COPY libraries/validation-tools/ /overleaf/libraries/validation-tools/
 COPY services/notifications/ /overleaf/services/notifications/
 COPY tools/migrations/ /overleaf/tools/migrations/
 
-ENV NODE_OPTIONS="--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs"
-
 FROM app
 USER node
 

+ 3 - 5
services/notifications/Makefile

@@ -70,11 +70,9 @@ clean:
 # Eslint and prettier (plus some configs) are on the root.
 RUN_LINTING = ../../bin/run -w /overleaf/services/$(PROJECT_NAME) monorepo yarn run --silent
 RUN_LINTING_MONOREPO = ../../bin/run monorepo yarn run --silent
-RUN_EXEC_MONOREPO = ../../bin/run monorepo yarn exec
 
 RUN_LINTING_CI = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/notifications/reports:/overleaf/services/notifications/reports --volume $(MONOREPO)/.cache:/overleaf/.cache $(IMAGE_CI) yarn run --silent
 RUN_LINTING_CI_MONOREPO = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/notifications/reports:/overleaf/services/notifications/reports --volume $(MONOREPO)/.cache:/overleaf/.cache -w /overleaf $(IMAGE_CI) yarn run --silent
-RUN_EXEC_CI_MONOREPO = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/notifications/reports:/overleaf/services/notifications/reports --volume $(MONOREPO)/.cache:/overleaf/.cache -w /overleaf $(IMAGE_CI) yarn exec
 
 SHELLCHECK_OPTS = \
 	--shell=bash \
@@ -122,14 +120,14 @@ format_fix:
 	$(RUN_LINTING_MONOREPO) format:fix services/notifications
 
 lint:
-	$(RUN_EXEC_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --max-warnings 0 --format unix services/notifications
+	$(RUN_LINTING) lint
 
 lint_ci:
-	-$(RUN_EXEC_CI_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --max-warnings 0 --format json --output-file services/notifications/reports/eslint.json services/notifications
+	-$(RUN_LINTING_CI) lint --format json --output-file reports/eslint.json
 	sed -i 's_"filePath":"/overleaf_"filePath":"$(MONOREPO)_g' reports/eslint.json
 
 lint_fix:
-	$(RUN_EXEC_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --fix services/notifications
+	$(RUN_LINTING) lint:fix
 
 typecheck:
 	$(RUN_LINTING) types:check

+ 4 - 8
services/notifications/docker-compose.yml

@@ -10,14 +10,12 @@ services:
       target: base
     volumes:
       - .:/overleaf/services/notifications
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../package.json:/overleaf/package.json
       - ../../.yarnrc.yml:/overleaf/.yarnrc.yml
       - ../../yarn.lock:/overleaf/yarn.lock
       - ../../.yarn:/overleaf/.yarn
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
       - ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
       - ../../tools/migrations:/overleaf/tools/migrations
       - ../../tsconfig.backend.json:/overleaf/tsconfig.backend.json
@@ -27,7 +25,7 @@ services:
       LOG_LEVEL: ${LOG_LEVEL:-}
       MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
       NODE_ENV: test
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs --unhandled-rejections=strict"
+      NODE_OPTIONS: "--unhandled-rejections=strict"
     entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
     command: yarn run --silent test:unit
     user: node
@@ -42,14 +40,12 @@ services:
       target: base
     volumes:
       - .:/overleaf/services/notifications
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../package.json:/overleaf/package.json
       - ../../.yarnrc.yml:/overleaf/.yarnrc.yml
       - ../../yarn.lock:/overleaf/yarn.lock
       - ../../.yarn:/overleaf/.yarn
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
       - ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
       - ../../tools/migrations:/overleaf/tools/migrations
       - ../../tsconfig.backend.json:/overleaf/tsconfig.backend.json
@@ -61,7 +57,7 @@ services:
       MOCHA_GREP: ${MOCHA_GREP}
       LOG_LEVEL: ${LOG_LEVEL:-}
       NODE_ENV: test
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs --unhandled-rejections=strict"
+      NODE_OPTIONS: "--unhandled-rejections=strict"
     user: node
     depends_on:
       mongo:

+ 0 - 3
services/notifications/package.json

@@ -30,17 +30,14 @@
     "body-parser": "1.20.4",
     "bunyan": "^1.8.15",
     "express": "4.22.1",
-    "mongodb": "6.12.0",
     "mongodb-legacy": "6.1.3",
     "zod": "^4.1.7",
     "zod-validation-error": "^4.0.1"
   },
   "devDependencies": {
     "@overleaf/migrations": "workspace:*",
-    "@types/node": "^24.5.2",
     "chai": "^4.3.6",
     "chai-as-promised": "^7.1.1",
-    "eslint": "^10.4.0",
     "mocha": "^11.1.0",
     "typescript": "^5.0.4",
     "vitest": "4.1.5"

+ 1 - 1
services/notifications/test/acceptance/js/MongoHelper.ts

@@ -4,6 +4,6 @@ import { promisify } from 'node:util'
 
 beforeAll(async function () {
   await promisify(exec)(
-    `cd ../../tools/migrations && yarn run migrations migrate -t server-ce`
+    `cd ../../tools/migrations && npm run migrations -- migrate -t server-ce`
   )
 }, 60_000)

+ 3 - 8
services/project-history/Dockerfile

@@ -5,6 +5,7 @@
 FROM node:24.14.1 AS base
 
 # Corepack setup, shared between all the images.
+ENV PATH="/overleaf/node_modules/.bin:$PATH"
 ENV COREPACK_HOME=/opt/corepack
 RUN corepack enable && corepack install -g yarn@4.14.1
 ENV COREPACK_ENABLE_NETWORK=0
@@ -17,7 +18,7 @@ RUN mkdir /home/node/.config && chown node:node /home/node/.config
 
 FROM base AS app
 
-COPY package.json yarn.lock .yarnrc.yml .pnp.register.mjs /overleaf/
+COPY package.json yarn.lock .yarnrc.yml /overleaf/
 COPY libraries/eslint-plugin/package.json /overleaf/libraries/eslint-plugin/package.json
 COPY libraries/fetch-utils/package.json /overleaf/libraries/fetch-utils/package.json
 COPY libraries/logger/package.json /overleaf/libraries/logger/package.json
@@ -26,18 +27,16 @@ COPY libraries/mongo-utils/package.json /overleaf/libraries/mongo-utils/package.
 COPY libraries/o-error/package.json /overleaf/libraries/o-error/package.json
 COPY libraries/overleaf-editor-core/package.json /overleaf/libraries/overleaf-editor-core/package.json
 COPY libraries/promise-utils/package.json /overleaf/libraries/promise-utils/package.json
-COPY libraries/ranges-tracker/package.json /overleaf/libraries/ranges-tracker/package.json
 COPY libraries/redis-wrapper/package.json /overleaf/libraries/redis-wrapper/package.json
 COPY libraries/settings/package.json /overleaf/libraries/settings/package.json
 COPY libraries/stream-utils/package.json /overleaf/libraries/stream-utils/package.json
 COPY libraries/validation-tools/package.json /overleaf/libraries/validation-tools/package.json
-COPY services/document-updater/package.json /overleaf/services/document-updater/package.json
 COPY services/project-history/package.json /overleaf/services/project-history/package.json
 COPY tools/migrations/package.json /overleaf/tools/migrations/package.json
 COPY .yarn/patches/ /overleaf/.yarn/patches/
 COPY tools/migrations/ /overleaf/tools/migrations/
 
-RUN cd /overleaf && yarn workspaces focus @overleaf/project-history @overleaf/document-updater overleaf
+RUN cd /overleaf && yarn workspaces focus @overleaf/project-history overleaf
 COPY libraries/eslint-plugin/ /overleaf/libraries/eslint-plugin/
 COPY libraries/fetch-utils/ /overleaf/libraries/fetch-utils/
 COPY libraries/logger/ /overleaf/libraries/logger/
@@ -46,17 +45,13 @@ COPY libraries/mongo-utils/ /overleaf/libraries/mongo-utils/
 COPY libraries/o-error/ /overleaf/libraries/o-error/
 COPY libraries/overleaf-editor-core/ /overleaf/libraries/overleaf-editor-core/
 COPY libraries/promise-utils/ /overleaf/libraries/promise-utils/
-COPY libraries/ranges-tracker/ /overleaf/libraries/ranges-tracker/
 COPY libraries/redis-wrapper/ /overleaf/libraries/redis-wrapper/
 COPY libraries/settings/ /overleaf/libraries/settings/
 COPY libraries/stream-utils/ /overleaf/libraries/stream-utils/
 COPY libraries/validation-tools/ /overleaf/libraries/validation-tools/
-COPY services/document-updater/ /overleaf/services/document-updater/
 COPY services/project-history/ /overleaf/services/project-history/
 COPY tools/migrations/ /overleaf/tools/migrations/
 
-ENV NODE_OPTIONS="--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs"
-
 FROM app
 USER node
 

+ 3 - 7
services/project-history/Makefile

@@ -24,12 +24,10 @@ IMAGE_CACHE ?= $(IMAGE_REPO):cache-$(shell cat \
 	$(MONOREPO)/libraries/o-error/package.json \
 	$(MONOREPO)/libraries/overleaf-editor-core/package.json \
 	$(MONOREPO)/libraries/promise-utils/package.json \
-	$(MONOREPO)/libraries/ranges-tracker/package.json \
 	$(MONOREPO)/libraries/redis-wrapper/package.json \
 	$(MONOREPO)/libraries/settings/package.json \
 	$(MONOREPO)/libraries/stream-utils/package.json \
 	$(MONOREPO)/libraries/validation-tools/package.json \
-	$(MONOREPO)/services/document-updater/package.json \
 	$(MONOREPO)/services/project-history/package.json \
 	$(MONOREPO)/tools/migrations/package.json \
 	$(MONOREPO)/.yarn/patches/* \
@@ -75,11 +73,9 @@ clean:
 # Eslint and prettier (plus some configs) are on the root.
 RUN_LINTING = ../../bin/run -w /overleaf/services/$(PROJECT_NAME) monorepo yarn run --silent
 RUN_LINTING_MONOREPO = ../../bin/run monorepo yarn run --silent
-RUN_EXEC_MONOREPO = ../../bin/run monorepo yarn exec
 
 RUN_LINTING_CI = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/document-updater/app/js/types.ts:/overleaf/services/document-updater/app/js/types.ts --volume $(MONOREPO)/services/project-history/reports:/overleaf/services/project-history/reports --volume $(MONOREPO)/.cache:/overleaf/.cache $(IMAGE_CI) yarn run --silent
 RUN_LINTING_CI_MONOREPO = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/document-updater/app/js/types.ts:/overleaf/services/document-updater/app/js/types.ts --volume $(MONOREPO)/services/project-history/reports:/overleaf/services/project-history/reports --volume $(MONOREPO)/.cache:/overleaf/.cache -w /overleaf $(IMAGE_CI) yarn run --silent
-RUN_EXEC_CI_MONOREPO = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/document-updater/app/js/types.ts:/overleaf/services/document-updater/app/js/types.ts --volume $(MONOREPO)/services/project-history/reports:/overleaf/services/project-history/reports --volume $(MONOREPO)/.cache:/overleaf/.cache -w /overleaf $(IMAGE_CI) yarn exec
 
 SHELLCHECK_OPTS = \
 	--shell=bash \
@@ -127,14 +123,14 @@ format_fix:
 	$(RUN_LINTING_MONOREPO) format:fix services/project-history
 
 lint:
-	$(RUN_EXEC_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --max-warnings 0 --format unix services/project-history
+	$(RUN_LINTING) lint
 
 lint_ci:
-	-$(RUN_EXEC_CI_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --max-warnings 0 --format json --output-file services/project-history/reports/eslint.json services/project-history
+	-$(RUN_LINTING_CI) lint --format json --output-file reports/eslint.json
 	sed -i 's_"filePath":"/overleaf_"filePath":"$(MONOREPO)_g' reports/eslint.json
 
 lint_fix:
-	$(RUN_EXEC_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --fix services/project-history
+	$(RUN_LINTING) lint:fix
 
 typecheck:
 	$(RUN_LINTING) types:check

+ 0 - 1
services/project-history/buildscript.txt

@@ -4,7 +4,6 @@ project-history
 --env-add=
 --env-pass-through=
 --esmock-loader=True
---extra-focus-packages=@overleaf/document-updater
 --node-version=24.14.1
 --package-name=@overleaf/project-history
 --pipeline-owner=44

+ 4 - 8
services/project-history/docker-compose.yml

@@ -10,14 +10,12 @@ services:
       target: base
     volumes:
       - .:/overleaf/services/project-history
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../package.json:/overleaf/package.json
       - ../../.yarnrc.yml:/overleaf/.yarnrc.yml
       - ../../yarn.lock:/overleaf/yarn.lock
       - ../../.yarn:/overleaf/.yarn
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
       - ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
       - ../../tools/migrations:/overleaf/tools/migrations
     working_dir: /overleaf/services/project-history
@@ -26,7 +24,7 @@ services:
       LOG_LEVEL: ${LOG_LEVEL:-}
       MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
       NODE_ENV: test
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs --unhandled-rejections=strict"
+      NODE_OPTIONS: "--unhandled-rejections=strict"
       REDIS_HOST: redis_test
       HISTORY_REDIS_HOST: redis_test
       QUEUES_REDIS_HOST: redis_test
@@ -48,14 +46,12 @@ services:
       target: base
     volumes:
       - .:/overleaf/services/project-history
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../package.json:/overleaf/package.json
       - ../../.yarnrc.yml:/overleaf/.yarnrc.yml
       - ../../yarn.lock:/overleaf/yarn.lock
       - ../../.yarn:/overleaf/.yarn
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
       - ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
       - ../../tools/migrations:/overleaf/tools/migrations
     working_dir: /overleaf/services/project-history
@@ -71,7 +67,7 @@ services:
       MOCHA_GREP: ${MOCHA_GREP}
       LOG_LEVEL: ${LOG_LEVEL:-}
       NODE_ENV: test
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs --unhandled-rejections=strict"
+      NODE_OPTIONS: "--unhandled-rejections=strict"
     user: node
     depends_on:
       mongo:

+ 1 - 5
services/project-history/package.json

@@ -33,22 +33,18 @@
     "express": "4.22.1",
     "lodash": "^4.18.1",
     "minimist": "^1.2.8",
-    "mongodb": "6.12.0",
     "mongodb-legacy": "6.1.3",
     "overleaf-editor-core": "workspace:*",
     "p-queue": "^8.1.0"
   },
   "devDependencies": {
     "@overleaf/migrations": "workspace:*",
-    "@types/node": "^24.5.2",
     "chai": "^4.3.6",
     "chai-as-promised": "^7.1.1",
-    "eslint": "^10.4.0",
-    "esmock": "patch:esmock@npm%3A2.7.3#~/.yarn/patches/esmock-npm-2.7.3-83624b28f6.patch",
+    "esmock": "^2.7.3",
     "mocha": "^11.1.0",
     "mocha-junit-reporter": "^2.2.1",
     "mocha-multi-reporters": "^1.5.1",
-    "mongodb": "6.12.0",
     "nock": "^13.5.3",
     "sinon": "~9.0.1",
     "sinon-chai": "^3.7.0",

+ 1 - 1
services/project-history/test/acceptance/js/helpers/MongoHelper.js

@@ -5,6 +5,6 @@ before('run migrations', async function () {
   this.timeout(60_000)
 
   await promisify(exec)(
-    `cd ../../tools/migrations && yarn run migrations migrate -t server-ce`
+    `cd ../../tools/migrations && npm run migrations -- migrate -t server-ce`
   )
 })

+ 2 - 3
services/real-time/Dockerfile

@@ -5,6 +5,7 @@
 FROM node:24.14.1 AS base
 
 # Corepack setup, shared between all the images.
+ENV PATH="/overleaf/node_modules/.bin:$PATH"
 ENV COREPACK_HOME=/opt/corepack
 RUN corepack enable && corepack install -g yarn@4.14.1
 ENV COREPACK_ENABLE_NETWORK=0
@@ -17,7 +18,7 @@ RUN mkdir /home/node/.config && chown node:node /home/node/.config
 
 FROM base AS app
 
-COPY package.json yarn.lock .yarnrc.yml .pnp.register.mjs /overleaf/
+COPY package.json yarn.lock .yarnrc.yml /overleaf/
 COPY libraries/eslint-plugin/package.json /overleaf/libraries/eslint-plugin/package.json
 COPY libraries/fetch-utils/package.json /overleaf/libraries/fetch-utils/package.json
 COPY libraries/logger/package.json /overleaf/libraries/logger/package.json
@@ -42,8 +43,6 @@ COPY libraries/settings/ /overleaf/libraries/settings/
 COPY libraries/validation-tools/ /overleaf/libraries/validation-tools/
 COPY services/real-time/ /overleaf/services/real-time/
 
-ENV NODE_OPTIONS="--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs"
-
 FROM app
 USER node
 

+ 3 - 5
services/real-time/Makefile

@@ -69,11 +69,9 @@ clean:
 # Eslint and prettier (plus some configs) are on the root.
 RUN_LINTING = ../../bin/run -w /overleaf/services/$(PROJECT_NAME) monorepo yarn run --silent
 RUN_LINTING_MONOREPO = ../../bin/run monorepo yarn run --silent
-RUN_EXEC_MONOREPO = ../../bin/run monorepo yarn exec
 
 RUN_LINTING_CI = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/real-time/reports:/overleaf/services/real-time/reports --volume $(MONOREPO)/.cache:/overleaf/.cache $(IMAGE_CI) yarn run --silent
 RUN_LINTING_CI_MONOREPO = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/real-time/reports:/overleaf/services/real-time/reports --volume $(MONOREPO)/.cache:/overleaf/.cache -w /overleaf $(IMAGE_CI) yarn run --silent
-RUN_EXEC_CI_MONOREPO = docker run --rm --volume $(MONOREPO)/.editorconfig:/overleaf/.editorconfig --volume $(MONOREPO)/eslint.config.mjs:/overleaf/eslint.config.mjs --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume $(MONOREPO)/tsconfig.backend.json:/overleaf/tsconfig.backend.json --volume $(MONOREPO)/services/real-time/reports:/overleaf/services/real-time/reports --volume $(MONOREPO)/.cache:/overleaf/.cache -w /overleaf $(IMAGE_CI) yarn exec
 
 SHELLCHECK_OPTS = \
 	--shell=bash \
@@ -121,14 +119,14 @@ format_fix:
 	$(RUN_LINTING_MONOREPO) format:fix services/real-time
 
 lint:
-	$(RUN_EXEC_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --max-warnings 0 --format unix services/real-time
+	$(RUN_LINTING) lint
 
 lint_ci:
-	-$(RUN_EXEC_CI_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --max-warnings 0 --format json --output-file services/real-time/reports/eslint.json services/real-time
+	-$(RUN_LINTING_CI) lint --format json --output-file reports/eslint.json
 	sed -i 's_"filePath":"/overleaf_"filePath":"$(MONOREPO)_g' reports/eslint.json
 
 lint_fix:
-	$(RUN_EXEC_MONOREPO) eslint --cache --cache-location ./.cache/eslint/ --fix services/real-time
+	$(RUN_LINTING) lint:fix
 
 typecheck:
 	$(RUN_LINTING) types:check

+ 4 - 8
services/real-time/docker-compose.yml

@@ -10,14 +10,12 @@ services:
       target: base
     volumes:
       - .:/overleaf/services/real-time
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../package.json:/overleaf/package.json
       - ../../.yarnrc.yml:/overleaf/.yarnrc.yml
       - ../../yarn.lock:/overleaf/yarn.lock
       - ../../.yarn:/overleaf/.yarn
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
       - ../../tsconfig.backend.json:/overleaf/tsconfig.backend.json
     working_dir: /overleaf/services/real-time
     environment:
@@ -25,7 +23,7 @@ services:
       LOG_LEVEL: ${LOG_LEVEL:-}
       MONGO_CONNECTION_STRING: mongodb://mongo/test-overleaf
       NODE_ENV: test
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs --unhandled-rejections=strict"
+      NODE_OPTIONS: "--unhandled-rejections=strict"
       REDIS_HOST: redis_test
       HISTORY_REDIS_HOST: redis_test
       QUEUES_REDIS_HOST: redis_test
@@ -44,14 +42,12 @@ services:
       target: base
     volumes:
       - .:/overleaf/services/real-time
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../package.json:/overleaf/package.json
       - ../../.yarnrc.yml:/overleaf/.yarnrc.yml
       - ../../yarn.lock:/overleaf/yarn.lock
       - ../../.yarn:/overleaf/.yarn
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
     working_dir: /overleaf/services/real-time
     environment:
       RETRIES:
@@ -65,7 +61,7 @@ services:
       MOCHA_GREP: ${MOCHA_GREP}
       LOG_LEVEL: ${LOG_LEVEL:-}
       NODE_ENV: test
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs --unhandled-rejections=strict"
+      NODE_OPTIONS: "--unhandled-rejections=strict"
     user: node
     depends_on:
       redis_test:

+ 0 - 3
services/real-time/package.json

@@ -36,15 +36,12 @@
     "proxy-addr": "^2.0.7",
     "socket.io": "github:overleaf/socket.io#0.9.19-overleaf-12",
     "socket.io-client": "github:overleaf/socket.io-client#0.9.17-overleaf-5",
-    "zod": "^3.24.0",
     "zod-validation-error": "^4.0.1"
   },
   "devDependencies": {
-    "@types/node": "^24.5.2",
     "chai": "^4.3.6",
     "chai-as-promised": "^7.1.1",
     "cookie-signature": "^1.1.0",
-    "eslint": "^10.4.0",
     "mocha": "^11.1.0",
     "mocha-junit-reporter": "^2.2.1",
     "mocha-multi-reporters": "^1.5.1",

+ 0 - 1
services/web/.gitignore

@@ -22,7 +22,6 @@ cypress/screenshots/
 cypress/videos/
 cypress/downloads/
 cypress/results/
-cypress/reporter/
 
 # Ace themes for conversion
 frontend/js/features/source-editor/themes/ace/

+ 0 - 3
services/web/.storybook/main.ts

@@ -127,9 +127,6 @@ export default defineMain({
             rootDir,
             'modules/writefull/frontend/js/integration/src/'
           ),
-          // Allow all packages to resolve core-js (injected by Babel's
-          // useBuiltIns: 'usage') even under Yarn PnP strict resolution.
-          'core-js': path.dirname(require.resolve('core-js/package.json')),
         },
       },
       module: {

+ 2 - 2
services/web/Dockerfile

@@ -4,6 +4,7 @@
 FROM node:24.14.1 AS base
 
 # Corepack setup, shared between all the images.
+ENV PATH="/overleaf/node_modules/.bin:$PATH"
 ENV COREPACK_HOME=/opt/corepack
 RUN corepack enable && corepack install -g yarn@4.14.1
 ENV COREPACK_ENABLE_NETWORK=0
@@ -35,7 +36,7 @@ FROM base AS deps-prod
 COPY services/web/scripts/fetch-pyodide-packages.mjs /overleaf/services/web/scripts/fetch-pyodide-packages.mjs
 RUN cd /overleaf/services/web && node scripts/fetch-pyodide-packages.mjs
 
-COPY package.json yarn.lock .yarnrc.yml .pnp.register.mjs /overleaf/
+COPY package.json yarn.lock .yarnrc.yml /overleaf/
 COPY libraries/access-token-encryptor/package.json /overleaf/libraries/access-token-encryptor/package.json
 COPY libraries/eslint-plugin/package.json /overleaf/libraries/eslint-plugin/package.json
 COPY libraries/fetch-utils/package.json /overleaf/libraries/fetch-utils/package.json
@@ -132,7 +133,6 @@ COPY tools/migrations/ /overleaf/tools/migrations/
 RUN rm /overleaf/services/web/modules/server-ce-scripts -rf
 RUN OVERLEAF_CONFIG=/overleaf/services/web/config/settings.overrides.saas.js nice yarn run precompile-pug
 
-ENV NODE_OPTIONS="--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs"
 
 # the web image with only production dependencies but no webpack production build, for development
 FROM pug AS app-only

+ 3 - 4
services/web/Makefile

@@ -499,9 +499,9 @@ RUN_LINTING_MONOREPO = ../../bin/run monorepo yarn run --silent
 
 ORG_PATH = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
 RUN_LINT_FORMAT ?= \
-	docker run --rm --env BRANCH_NAME --env CI --env COMMIT_SHA --env MONOREPO --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume ${PWD}/data/reports:/overleaf/services/web/data/reports --volume $(MONOREPO)/.cache/:/overleaf/.cache/ ${IMAGE_CI}
+	docker run --rm --env BRANCH_NAME --env CI --env COMMIT_SHA --env MONOREPO --env PATH=/overleaf/node_modules/.bin:$(ORG_PATH) --volume $(MONOREPO)/.prettierignore:/overleaf/.prettierignore --volume $(MONOREPO)/.prettierrc.cjs:/overleaf/.prettierrc.cjs --volume ${PWD}/data/reports:/overleaf/services/web/data/reports --volume $(MONOREPO)/.cache/:/overleaf/.cache/ ${IMAGE_CI}
 
-NODE_MODULES_PATH := ${PATH}
+NODE_MODULES_PATH := ${PATH}:${PWD}/node_modules/.bin:/overleaf/services/web/node_modules/.bin
 WITH_NODE_MODULES_PATH = \
 	format_backend \
 	format_frontend \
@@ -583,7 +583,7 @@ lint_flag_res_send_usage:
 
 lint: lint_overleafModuleImports
 lint_overleafModuleImports:
-	yarn node scripts/check_overleafModuleImports.mjs
+	node scripts/check_overleafModuleImports.mjs
 
 lint: typecheck_frontend
 typecheck_frontend:
@@ -668,7 +668,6 @@ IMAGE_CACHE ?= $(IMAGE_REPO):cache-$(shell cat \
 	$(MONOREPO)/package.json \
 	$(MONOREPO)/yarn.lock \
 	$(MONOREPO)/libraries/access-token-encryptor/package.json \
-	$(MONOREPO)/libraries/eslint-config/package.json \
   $(MONOREPO)/libraries/eslint-plugin/package.json \
   $(MONOREPO)/libraries/fetch-utils/package.json \
   $(MONOREPO)/libraries/logger/package.json \

+ 1 - 1
services/web/bin/check_extracted_translations

@@ -5,7 +5,7 @@ set -e
 # Ensure all locales used in the frontend are tracked
 OUTPUT=data/dumpFolder/i18next-scanner
 trap 'rm -rf "$OUTPUT"' EXIT
-yarn exec i18next-scanner --output "$OUTPUT"
+npx i18next-scanner --output "$OUTPUT"
 ACTUAL=frontend/extracted-translations.json
 EXPECTED="$OUTPUT/frontend/extracted-translations.json"
 if ! diff "$ACTUAL" "$EXPECTED"; then

+ 1 - 4
services/web/cypress.config.ts

@@ -1,13 +1,10 @@
 import { defineConfig } from 'cypress'
 import { webpackConfig } from './cypress/support/webpack.cypress'
 
-// Cypress's Electron process uses PackherdModuleLoader which doesn't go through
-// PnP hooks. Reporter packages are materialized into /tmp/cypress-reporter by
-// scripts/materialize-cypress-reporter.js at container startup.
 let reporterOptions = {}
 if (process.env.CI) {
   reporterOptions = {
-    reporter: '/tmp/cypress-reporter/node_modules/cypress-multi-reporters',
+    reporter: 'cypress-multi-reporters',
     reporterOptions: {
       configFile: 'cypress/cypress-multi-reporters.json',
     },

+ 9 - 22
services/web/docker-compose.yml

@@ -9,9 +9,7 @@ services:
       target: base
     volumes:
       - .:/overleaf/services/web
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
       - ../../tools/migrations:/overleaf/tools/migrations
@@ -32,7 +30,7 @@ services:
       MOCHA_GREP: ${MOCHA_GREP:-}
       LOG_LEVEL: ${LOG_LEVEL:-}
       NODE_ENV: test
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs --unhandled-rejections=strict"
+      NODE_OPTIONS: "--unhandled-rejections=strict"
       REDIS_HOST: redis_test
       MONOREPO:
     entrypoint: /overleaf/bin/shared/wait_for_it mongo:27017 --timeout=60 --
@@ -49,9 +47,7 @@ services:
       target: base
     volumes:
       - .:/overleaf/services/web
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../bin/shared/wait_for_it:/overleaf/bin/shared/wait_for_it
       - ../../tools/migrations:/overleaf/tools/migrations
@@ -73,7 +69,6 @@ services:
       LOG_LEVEL: ${LOG_LEVEL:-}
       MONGO_SERVER_SELECTION_TIMEOUT: 600000
       MONGO_SOCKET_TIMEOUT: 300000
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs --unhandled-rejections=strict"
       REDIS_HOST: redis_test
       MONOREPO:
       RETRIES:
@@ -96,9 +91,7 @@ services:
       target: base
     volumes:
       - .:/overleaf/services/web
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../package.json:/overleaf/package.json
       - ../../.yarnrc.yml:/overleaf/.yarnrc.yml
@@ -109,7 +102,7 @@ services:
       CI:
       JUNIT_ROOT_SUITE_NAME:
       MOCHA_GREP: ${MOCHA_GREP}
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs --unhandled-rejections=strict"
+      NODE_OPTIONS: "--unhandled-rejections=strict"
       VERBOSE_LOGGING:
     command: yarn run --silent test:frontend
     user: node
@@ -122,10 +115,7 @@ services:
         - USER_GID
     volumes:
       - .:/overleaf/services/web
-      - ../../scripts:/overleaf/scripts:ro
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../package.json:/overleaf/package.json
       - ../../.yarnrc.yml:/overleaf/.yarnrc.yml
@@ -138,8 +128,7 @@ services:
       JUNIT_ROOT_SUITE_NAME:
       CYPRESS_SPEC_PATTERN: ${CYPRESS_SPEC_PATTERN:-}
       CYPRESS_EXCLUDE_SPEC_PATTERN: ${CYPRESS_EXCLUDE_SPEC_PATTERN:-}
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs"
-    entrypoint: yarn
+    entrypoint: npm
     command:
       - "run"
       - "cypress:run-ct"
@@ -151,9 +140,7 @@ services:
       target: base
     volumes:
       - .:/overleaf/services/web
-      - ../../.pnp.cjs:/overleaf/.pnp.cjs
-      - ../../.pnp.loader.mjs:/overleaf/.pnp.loader.mjs
-      - ../../.pnp.register.mjs:/overleaf/.pnp.register.mjs
+      - ../../node_modules:/overleaf/node_modules
       - ../../libraries:/overleaf/libraries
       - ../../package.json:/overleaf/package.json
       - ../../.yarnrc.yml:/overleaf/.yarnrc.yml
@@ -163,7 +150,7 @@ services:
     environment:
       CI:
       JUNIT_ROOT_SUITE_NAME:
-      NODE_OPTIONS: "--require /overleaf/.pnp.cjs --import /overleaf/.pnp.register.mjs --unhandled-rejections=strict"
+      NODE_OPTIONS: "--unhandled-rejections=strict"
       VERBOSE_LOGGING:
     command: yarn run --silent test:writefull
     user: node

+ 3 - 26
services/web/package.json

@@ -3,10 +3,6 @@
   "description": "The HTTP front end for Overleaf",
   "private": true,
   "main": "app.mjs",
-  "exports": {
-    ".": "./app.mjs",
-    "./*": "./*"
-  },
   "directories": {
     "public": "./public"
   },
@@ -40,9 +36,8 @@
     "type-check:backend": "tsc -p tsconfig.backend.json --noEmit",
     "extract-translations": "i18next-scanner",
     "convert-themes": "node frontend/js/features/source-editor/themes/scripts/convert.js",
-    "materialize-reporter": "node scripts/materialize-cypress-reporter.js /tmp/cypress-reporter",
-    "cypress:open-ct": "yarn run materialize-reporter && OVERLEAF_CONFIG=$(pwd)/config/settings.webpack.js cypress open --component",
-    "cypress:run-ct": "yarn run materialize-reporter && OVERLEAF_CONFIG=$(pwd)/config/settings.webpack.js cypress run --component --browser chrome",
+    "cypress:open-ct": "OVERLEAF_CONFIG=$(pwd)/config/settings.webpack.js cypress open --component",
+    "cypress:run-ct": "OVERLEAF_CONFIG=$(pwd)/config/settings.webpack.js cypress run --component --browser chrome",
     "cypress:docker:open-ct": "USER_UID=$(id -u) USER_GID=$(id -g) docker compose -f docker-compose.cypress.yml run --rm cypress yarn run cypress:open-ct",
     "cypress:docker:run-ct": "USER_UID=$(id -u) USER_GID=$(id -g) docker compose -f docker-compose.cypress.yml run --rm cypress yarn run cypress:run-ct --browser chrome",
     "lezer-latex:generate": "node scripts/lezer-latex/generate.mjs",
@@ -157,7 +152,6 @@
     "minimist": "^1.2.7",
     "mmmagic": "^0.5.3",
     "moment": "^2.29.4",
-    "mongodb": "6.12.0",
     "mongodb-legacy": "6.1.3",
     "mongoose": "8.22.1",
     "multer": "2.1.1",
@@ -204,7 +198,6 @@
     "@ai-sdk/react": "^3.0.172",
     "@babel/core": "^7.28.5",
     "@babel/plugin-proposal-decorators": "^7.28.0",
-    "@babel/plugin-transform-typescript": "^7.28.0",
     "@babel/preset-env": "^7.28.5",
     "@babel/preset-react": "^7.28.5",
     "@babel/preset-typescript": "^7.28.5",
@@ -242,7 +235,6 @@
     "@replit/codemirror-indentation-markers": "overleaf/codemirror-indentation-markers#371ce3b56f453a392eb0d3b85ab019c185c68e1f",
     "@replit/codemirror-vim": "overleaf/codemirror-vim#1bef138382d948018f3f9b8a4d7a70ab61774e4b",
     "@sentry/browser": "7.46.0",
-    "@sentry/types": "7.46.0",
     "@storybook/addon-a11y": "10.3.5",
     "@storybook/addon-designs": "^11.1.3",
     "@storybook/addon-docs": "10.3.5",
@@ -264,19 +256,15 @@
     "@types/async": "^3.2.25",
     "@types/bootstrap": "^5.2.10",
     "@types/chai": "^4.3.0",
-    "@types/chai-as-promised": "^8.0.2",
     "@types/dateformat": "^5.0.3",
     "@types/diff": "^5.2.3",
     "@types/dom-speech-recognition": "^0.0.7",
     "@types/events": "^3.0.3",
     "@types/express": "^4.17.23",
-    "@types/lodash": "^4.17.24",
-    "@types/mdast": "^4.0.4",
     "@types/minimist": "^1.2.5",
     "@types/mocha": "^9.1.0",
     "@types/mocha-each": "^2.0.4",
     "@types/node": "^24.5.2",
-    "@types/path-browserify": "^1.0.3",
     "@types/react": "^18.3.20",
     "@types/react-color": "^3.0.13",
     "@types/react-dom": "^18.3.6",
@@ -285,19 +273,15 @@
     "@types/react-syntax-highlighter": "^15.5.11",
     "@types/recurly__recurly-js": "^4.38.0",
     "@types/sanitize-html": "^2.14.0",
-    "@types/sinon": "^21.0.1",
     "@types/sinon-chai": "^3.2.12",
     "@types/utf-8-validate": "^5.0.2",
     "@types/uuid": "^10.0.0",
-    "@typescript-eslint/eslint-plugin": "^8.59.4",
-    "@typescript-eslint/parser": "^8.59.4",
     "@uppy/core": "^3.8.0",
     "@uppy/dashboard": "3.7.1",
     "@uppy/drag-drop": "3.0.3",
     "@uppy/file-input": "3.0.4",
     "@uppy/progress-bar": "3.0.4",
     "@uppy/react": "3.2.1",
-    "@uppy/status-bar": "^3.2.5",
     "@uppy/utils": "^5.7.0",
     "@uppy/xhr-upload": "3.6.0",
     "@vitest/coverage-istanbul": "^4.0.17",
@@ -332,8 +316,6 @@
     "core-js": "~3.46.0",
     "css-loader": "^7.1.4",
     "css-minimizer-webpack-plugin": "^8.0.0",
-    "csv-parse": "^6.2.1",
-    "csv-stringify": "^6.7.0",
     "cypress": "15.12.0",
     "cypress-multi-reporters": "^2.0.5",
     "cypress-plugin-tab": "^1.0.5",
@@ -344,12 +326,9 @@
     "downshift": "^9.0.9",
     "es6-promise": "^4.2.8",
     "escodegen": "^2.0.0",
-    "eslint": "^10.4.0",
     "eslint-config-prettier": "^10.1.8",
-    "eslint-formatter-unix": "^8.40.0",
     "eslint-plugin-chai-expect": "^4.1.0",
     "eslint-plugin-chai-friendly": "^1.2.0",
-    "eslint-plugin-cypress": "^4.1.0",
     "eslint-plugin-import": "^2.32.0",
     "eslint-plugin-jsx-a11y": "^6.10.2",
     "eslint-plugin-mocha": "^11.3.0",
@@ -365,7 +344,6 @@
     "fake-indexeddb": "^6.0.0",
     "fast-fuzzy": "^1.12.0",
     "fetch-mock": "^12.6.0",
-    "focus-trap": "^8.2.1",
     "formik": "^2.2.9",
     "glob": "^12.0.0",
     "globals": "^17.6.0",
@@ -441,9 +419,8 @@
     "timekeeper": "^2.2.0",
     "to-string-loader": "^1.2.0",
     "ts-loader": "^9.5.7",
-    "tslib": "^2.8.1",
     "tty-browserify": "^0.0.1",
-    "typescript": "^5.0.4",
+    "typescript": "^5.9.3",
     "unified": "^11.0.5",
     "unist-util-visit": "^5.0.0",
     "use-stick-to-bottom": "^1.1.1",

+ 1 - 1
services/web/scripts/learn/checkSanitize/checkSanitizeOptions.mjs

@@ -3,7 +3,7 @@ import fs from 'node:fs'
 import Path from 'node:path'
 import cheerio from 'cheerio'
 // checkSanitizeOptions is only used in dev env
-// eslint-disable-next-line import/no-extraneous-dependencies, import/no-unresolved
+// eslint-disable-next-line import/no-extraneous-dependencies
 import * as prettier from 'prettier'
 import sanitizeHtml from 'sanitize-html'
 import { sanitizeOptions } from '../../../modules/learn/app/src/sanitizeOptions.mjs'

+ 0 - 113
services/web/scripts/materialize-cypress-reporter.js

@@ -1,113 +0,0 @@
-#!/usr/bin/env node
-'use strict'
-/**
- * Materialize Cypress reporter packages (and their transitive dependencies)
- * into a real node_modules tree so that Cypress's Electron process (which uses
- * PackherdModuleLoader, NOT Yarn PnP hooks) can load them.
- *
- * Builds a NESTED node_modules structure (each package gets its own
- * node_modules/ for its deps) to avoid version conflicts from flat dedup.
- *
- * The target-dir must be OUTSIDE the PnP workspace root — otherwise PnP
- * intercepts requires from the materialized packages and blocks undeclared deps.
- *
- * Usage:  yarn node scripts/materialize-cypress-reporter.js <target-dir>
- */
-
-const path = require('path')
-const fs = require('fs')
-
-const targetDir = process.argv[2]
-if (!targetDir) {
-  console.error(
-    'Usage: yarn node scripts/materialize-cypress-reporter.js <target-dir>'
-  )
-  process.exit(1)
-}
-
-const pnp = require('module').findPnpApi(__filename)
-if (!pnp) {
-  console.log('Not running under PnP — nothing to do.')
-  process.exit(0)
-}
-
-let totalCopied = 0
-
-// PnP patches readFileSync/readdirSync/statSync but NOT cpSync.
-// Manual recursive copy to read from virtual/zip paths.
-function copyRecursive(src, dest) {
-  const stat = fs.statSync(src)
-  if (stat.isDirectory()) {
-    fs.mkdirSync(dest, { recursive: true })
-    for (const entry of fs.readdirSync(src)) {
-      copyRecursive(path.join(src, entry), path.join(dest, entry))
-    }
-  } else {
-    fs.mkdirSync(path.dirname(dest), { recursive: true })
-    fs.writeFileSync(dest, fs.readFileSync(src))
-  }
-}
-
-function resolvePkgDir(pkgName, issuer) {
-  // Use resolveToUnqualified to get the package directory without going
-  // through the package's exports map (which may not expose package.json).
-  let pkgDir = pnp.resolveToUnqualified(pkgName, issuer + '/')
-  if (pkgDir.endsWith('/')) pkgDir = pkgDir.slice(0, -1)
-  return pkgDir
-}
-
-/**
- * Materialize a package and its deps into destDir/node_modules/pkgName.
- * Each package's own deps get nested under its own node_modules/.
- */
-function materializeRecursive(pkgName, issuer, destNodeModules, seen) {
-  // Dedupe by destination path to avoid infinite loops, but allow the same
-  // package to appear in multiple locations (nested node_modules).
-  const key = `${destNodeModules}/${pkgName}`
-  if (seen.has(key)) return
-  seen.add(key)
-
-  let pkgDir
-  try {
-    pkgDir = resolvePkgDir(pkgName, issuer)
-  } catch {
-    return // optional/missing dep
-  }
-
-  const dest = path.join(destNodeModules, pkgName)
-  copyRecursive(pkgDir, dest)
-  totalCopied++
-
-  const pkg = JSON.parse(
-    fs.readFileSync(path.join(pkgDir, 'package.json'), 'utf8')
-  )
-  const deps = [
-    ...Object.keys(pkg.dependencies || {}),
-    ...Object.keys(pkg.peerDependencies || {}),
-  ]
-
-  if (deps.length > 0) {
-    const nestedNodeModules = path.join(dest, 'node_modules')
-    for (const dep of deps) {
-      materializeRecursive(dep, pkgDir, nestedNodeModules, seen)
-    }
-  }
-}
-
-const rootNodeModules = path.resolve(targetDir, 'node_modules')
-const seen = new Set()
-const topLevel = [
-  'cypress-multi-reporters',
-  'mocha-junit-reporter',
-  'typescript',
-]
-
-for (const pkg of topLevel) {
-  try {
-    materializeRecursive(pkg, process.cwd(), rootNodeModules, seen)
-  } catch (e) {
-    console.warn(`Warning: could not materialize ${pkg}: ${e.message}`)
-  }
-}
-
-console.log(`Materialized ${totalCopied} packages into ${rootNodeModules}`)

+ 2 - 2
services/web/scripts/translations/cleanupUnusedLocales.js

@@ -47,8 +47,8 @@ async function main() {
     {
       // run from services/web directory
       cwd: Path.join(__dirname, '../../'),
-      // 2GB
-      maxBuffer: 2 * 1024 * 1024 * 1024,
+      // 1GB
+      maxBuffer: 1024 * 1024 * 1024,
       // Docs: https://nodejs.org/docs/latest-v16.x/api/child_process.html#child_process_options_stdio
       // Entries are [stdin, stdout, stderr]
       stdio: ['ignore', 'pipe', 'inherit'],

+ 0 - 12
services/web/test/acceptance/bootstrap.js

@@ -1,15 +1,3 @@
-// Register PnP ESM loader via module.register() for synchronous ESM resolution
-// (--experimental-loader from yarn only works for async resolution)
-const { register } = require('node:module')
-const { pathToFileURL } = require('node:url')
-const path = require('node:path')
-const pnpRegister = path.resolve(__dirname, '../../.pnp.register.mjs')
-try {
-  register(pathToFileURL(pnpRegister), pathToFileURL(__filename))
-} catch {
-  // .pnp.register.mjs may not exist in non-PnP environments
-}
-
 const chai = require('chai')
 chai.should()
 chai.use(require('chai-as-promised'))

+ 1 - 2
services/web/test/acceptance/src/DeleteOrphanedDocsOnlineCheckTests.mjs

@@ -119,8 +119,7 @@ describe('DeleteOrphanedDocsOnlineCheck', function () {
             // Hide verbose log messages `calling destroy for project in docstore`
             'LOG_LEVEL=error',
             // Hide deprecation warnings for calling `db.collection.count`
-            // Preserve existing NODE_OPTIONS (e.g. PnP hooks) while adding --no-deprecation
-            `NODE_OPTIONS='${process.env.NODE_OPTIONS || ''} --no-deprecation'`,
+            'NODE_OPTIONS=--no-deprecation',
           ])
           .concat(['node', 'scripts/delete_orphaned_docs_online_check.mjs'])
           .join(' ')

+ 1 - 1
services/web/test/acceptance/src/helpers/MongoHelper.mjs

@@ -22,7 +22,7 @@ export default {
       this.timeout(60_000)
 
       await promisify(exec)(
-        `cd ../../tools/migrations && yarn run migrations migrate -t ${Settings.env || DEFAULT_ENV}`
+        `cd ../../tools/migrations && npm run migrations -- migrate -t ${Settings.env || DEFAULT_ENV}`
       )
     })
 

+ 0 - 2
services/web/test/unit/src/Settings/Settings.test.mjs

@@ -10,9 +10,7 @@ function clearSettingsCache() {
   const settingsDeps = Object.keys(require.cache).filter(
     x =>
       x.includes('/@overleaf/settings') ||
-      x.includes('/@overleaf-settings-virtual') ||
       x.includes(`${monorepoPath}/libraries/settings`) ||
-      x.includes('/libraries/settings/') ||
       x.includes(`${monorepoPath}/services/web/config`)
   )
   settingsDeps.forEach(dep => delete require.cache[dep])

+ 0 - 3
services/web/tsconfig.json

@@ -20,9 +20,6 @@
       "@modules/*": ["./modules/*"],
       "@overleaf/o-error": ["../../libraries/o-error"],
       "@overleaf/ranges-tracker": ["../../libraries/ranges-tracker"],
-      "@overleaf/validation-tools": ["../../libraries/validation-tools"],
-      "overleaf-editor-core": ["../../libraries/overleaf-editor-core"],
-      "overleaf-editor-core/*": ["../../libraries/overleaf-editor-core/*"],
 
       "@ol-types/*": ["./types/*"],
       "@ol-storybook/*": ["./.storybook/*"],

+ 0 - 11
services/web/types/uppy-utils.d.ts

@@ -1,11 +0,0 @@
-// Ambient module declaration for @uppy/utils subpath imports.
-// Under Yarn PnP, TypeScript cannot find the ambient declarations in
-// @uppy/utils/types/index.d.ts for deep imports like
-// @uppy/utils/lib/getDroppedFiles. Re-declare the subset we use here.
-declare module '@uppy/utils/lib/getDroppedFiles' {
-  function getDroppedFiles(
-    dataTransfer: DataTransfer,
-    options?: Record<string, unknown>
-  ): Promise<File[]>
-  export default getDroppedFiles
-}

+ 6 - 19
services/web/webpack.config.js

@@ -50,11 +50,13 @@ globSync(
 })
 
 function getModuleDirectory(moduleName) {
-  try {
-    return path.dirname(require.resolve(`${moduleName}/package.json`))
-  } catch (err) {
-    throw new Error(`could not find Node module: ${moduleName}`, { cause: err })
+  const entrypointPath = require.resolve(moduleName)
+  const suffix = `node_modules/${moduleName}`
+  const idx = entrypointPath.indexOf(suffix)
+  if (idx === -1) {
+    throw new Error(`could not find Node module: ${moduleName}`)
   }
+  return entrypointPath.slice(0, idx + suffix.length)
 }
 
 const mathjaxDir = getModuleDirectory('mathjax')
@@ -310,21 +312,6 @@ module.exports = {
       // Ensure all packages use the same jQuery instance (prevents duplicate
       // copies from Yarn hoisting breaking jQuery plugins like daterangepicker)
       jquery: require.resolve('jquery'),
-      // Under Yarn PnP, babel-injected core-js polyfill imports cannot be
-      // resolved from third-party packages (e.g. @uppy, pdfjs-dist) because
-      // they don't declare core-js as a dependency. Alias to the web
-      // workspace's copy so all packages can resolve it.
-      'core-js': path.dirname(require.resolve('core-js/package.json')),
-      // writefull's tsconfig uses importHelpers: true, which emits tslib
-      // imports that must be resolvable from the web workspace.
-      tslib: path.dirname(require.resolve('tslib/package.json')),
-      // Under PnP, packages like cypress/react that import react/react-dom
-      // can't resolve them from their own scope. Alias to web's copies.
-      react: path.dirname(require.resolve('react/package.json')),
-      'react-dom': path.dirname(require.resolve('react-dom/package.json')),
-      // ai-sdk packages declare zod as a peer dep but PnP can't resolve it
-      // from their scope in the Docker build.
-      zod: path.dirname(require.resolve('zod/package.json')),
     },
     // symlinks: false, // enable this while using `npm link`
     extensions: ['.js', '.jsx', '.ts', '.tsx', '.mjs', '.cjs', '.json'],

+ 0 - 3
tools/migrations/package.json

@@ -5,9 +5,6 @@
     "lint": "eslint --cache --cache-location ../../.cache/eslint/ --ext .cjs,.js,.jsx,.mjs,.ts --max-warnings 0 --format unix .",
     "lint:fix": "eslint --cache --cache-location ../../.cache/eslint/ --fix --ext .cjs,.js,.jsx,.mjs,.ts ."
   },
-  "devDependencies": {
-    "eslint": "^10.4.0"
-  },
   "dependencies": {
     "@overleaf/logger": "workspace:*",
     "@overleaf/mongo-utils": "workspace:*",

+ 0 - 1
tsconfig.backend.json

@@ -15,7 +15,6 @@
       "@overleaf/logger": ["./libraries/logger"],
       "@overleaf/metrics": ["./libraries/metrics"],
       "@overleaf/mongo-utils": ["./libraries/mongo-utils"],
-      "@overleaf/mongo-utils/*": ["./libraries/mongo-utils/*"],
       "@overleaf/object-persistor": ["./libraries/object-persistor"],
       "@overleaf/o-error": ["./libraries/o-error"],
       "overleaf-editor-core": ["./libraries/overleaf-editor-core"],

Diff do ficheiro suprimidas por serem muito extensas
+ 5 - 449
yarn.lock


Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff