[monorepo] turn throw statements in callback code into callback calls (#33524)

* [eslint-plugin] add rule for throw inside callback code

* [monorepo] enable our custom eslint plugins globally

* [monorepo] fix running make lint from root

* [monorepo] turn throw statements in callback code into callback calls

* [monorepo] add eslint-plugin libraries to all the Dockerfiles

* [monorepo] install eslint-plugin library at the root level

* [linked-url-proxy] add eslint-plugin library into Dockerfile

* [latexqc] add our eslint-plugin to eslint config

GitOrigin-RevId: b05e3ebbefb62370f2422e83880dd3913815270d
This commit is contained in:
Jakob Ackermann
2026-05-13 10:54:09 +02:00
committed by Copybot
parent d8df893593
commit b62d4814c3
30 changed files with 149 additions and 14 deletions

View File

@@ -8,5 +8,6 @@ module.exports = {
'require-vi-doMock-valid-path': require('./require-vi-doMock-valid-path'),
'require-loading-label': require('./require-loading-label'),
'require-cio-snake-case-properties': require('./require-cio-snake-case-properties'),
'no-throw-in-callback': require('./no-throw-in-callback'),
},
}

View File

@@ -0,0 +1,52 @@
const CALLBACK_PARAM_NAMES = new Set(['cb', 'callback', 'done', 'next'])
function isCallbackParam(param) {
return (
param && param.type === 'Identifier' && CALLBACK_PARAM_NAMES.has(param.name)
)
}
module.exports = {
meta: {
type: 'error',
docs: {
description: 'Disallow throw statements inside callback-based functions',
},
messages: {
noThrowInCallback:
'Pass the error to the callback instead of throwing in callback-based code.',
},
},
create(context) {
// Stack tracks whether each enclosing function is a callback-style function.
// A callback-style function is non-async and has a last param named cb/callback/done/next.
const stack = []
function enterFunction(node) {
const params = node.params
const isCallback =
!node.async &&
params.length > 0 &&
isCallbackParam(params[params.length - 1])
stack.push(isCallback)
}
function exitFunction() {
stack.pop()
}
return {
FunctionDeclaration: enterFunction,
'FunctionDeclaration:exit': exitFunction,
FunctionExpression: enterFunction,
'FunctionExpression:exit': exitFunction,
ArrowFunctionExpression: enterFunction,
'ArrowFunctionExpression:exit': exitFunction,
ThrowStatement(node) {
if (stack[stack.length - 1]) {
context.report({ node, messageId: 'noThrowInCallback' })
}
},
}
},
}

View File

@@ -1,4 +1,5 @@
const { RuleTester } = require('eslint')
const noThrowInCallback = require('./no-throw-in-callback')
const preferKebabUrl = require('./prefer-kebab-url')
const noUnnecessaryTrans = require('./no-unnecessary-trans')
const shouldUnescapeTrans = require('./should-unescape-trans')
@@ -267,3 +268,53 @@ ruleTester.run(
],
}
)
const noThrowInCallbackMessage =
'Pass the error to the callback instead of throwing in callback-based code.'
ruleTester.run('no-throw-in-callback', noThrowInCallback, {
valid: [
// Calling the callback with an error is fine
{ code: `function foo(cb) { cb(new Error()) }` },
// async functions may throw (they return a rejected promise)
{ code: `async function foo(cb) { throw new Error() }` },
// Last param not a callback name — not a callback-style function
{ code: `function foo(data) { throw new Error() }` },
// No params at all
{ code: `function foo() { throw new Error() }` },
// throw inside a nested non-callback function is fine
{ code: `function foo(cb) { [1].map(function() { throw new Error() }) }` },
// throw inside a nested async arrow is fine
{ code: `function foo(cb) { [1].map(async () => { throw new Error() }) }` },
],
invalid: [
{
code: `function foo(cb) { throw new Error() }`,
errors: [{ message: noThrowInCallbackMessage }],
},
{
code: `function foo(callback) { throw new Error() }`,
errors: [{ message: noThrowInCallbackMessage }],
},
{
code: `function foo(done) { throw new Error() }`,
errors: [{ message: noThrowInCallbackMessage }],
},
{
code: `function foo(next) { throw new Error() }`,
errors: [{ message: noThrowInCallbackMessage }],
},
{
code: `function foo(data, cb) { throw new Error() }`,
errors: [{ message: noThrowInCallbackMessage }],
},
{
code: `const foo = (cb) => { throw new Error() }`,
errors: [{ message: noThrowInCallbackMessage }],
},
// throw in a nested callback-style function inside another callback function
{
code: `function foo(cb) { bar(function(done) { throw new Error() }) }`,
errors: [{ message: noThrowInCallbackMessage }],
},
],
})

View File

@@ -3,6 +3,7 @@
"private": true,
"packageManager": "yarn@4.14.1",
"devDependencies": {
"@overleaf/eslint-plugin": "workspace:*",
"@prettier/plugin-pug": "^3.4.0",
"@types/chai": "^4.3.0",
"@types/chai-as-promised": "^7.1.8",

View File

@@ -19,6 +19,7 @@ RUN mkdir /home/node/.config && chown node:node /home/node/.config
FROM base AS app
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
COPY libraries/metrics/package.json /overleaf/libraries/metrics/package.json
@@ -32,6 +33,7 @@ COPY .yarn/patches/ /overleaf/.yarn/patches/
COPY tools/migrations/ /overleaf/tools/migrations/
RUN cd /overleaf && yarn workspaces focus @overleaf/chat overleaf
COPY libraries/eslint-plugin/ /overleaf/libraries/eslint-plugin/
COPY libraries/fetch-utils/ /overleaf/libraries/fetch-utils/
COPY libraries/logger/ /overleaf/libraries/logger/
COPY libraries/metrics/ /overleaf/libraries/metrics/

View File

@@ -16,6 +16,7 @@ IMAGE_REPO_FINAL ?= $(IMAGE_REPO):$(BRANCH_NAME_TAG_SAFE)-$(BUILD_NUMBER)
IMAGE_CACHE ?= $(IMAGE_REPO):cache-$(shell cat \
$(MONOREPO)/package.json \
$(MONOREPO)/yarn.lock \
$(MONOREPO)/libraries/eslint-plugin/package.json \
$(MONOREPO)/libraries/fetch-utils/package.json \
$(MONOREPO)/libraries/logger/package.json \
$(MONOREPO)/libraries/metrics/package.json \

View File

@@ -23,6 +23,7 @@ RUN mkdir /home/node/.config && chown node:node /home/node/.config
FROM base AS app
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
COPY libraries/metrics/package.json /overleaf/libraries/metrics/package.json
@@ -35,6 +36,7 @@ COPY services/clsi/package.json /overleaf/services/clsi/package.json
COPY .yarn/patches/ /overleaf/.yarn/patches/
RUN cd /overleaf && yarn workspaces focus @overleaf/clsi overleaf
COPY libraries/eslint-plugin/ /overleaf/libraries/eslint-plugin/
COPY libraries/fetch-utils/ /overleaf/libraries/fetch-utils/
COPY libraries/logger/ /overleaf/libraries/logger/
COPY libraries/metrics/ /overleaf/libraries/metrics/

View File

@@ -16,6 +16,7 @@ IMAGE_REPO_FINAL ?= $(IMAGE_REPO):$(BRANCH_NAME_TAG_SAFE)-$(BUILD_NUMBER)
IMAGE_CACHE ?= $(IMAGE_REPO):cache-$(shell cat \
$(MONOREPO)/package.json \
$(MONOREPO)/yarn.lock \
$(MONOREPO)/libraries/eslint-plugin/package.json \
$(MONOREPO)/libraries/fetch-utils/package.json \
$(MONOREPO)/libraries/logger/package.json \
$(MONOREPO)/libraries/metrics/package.json \

View File

@@ -19,6 +19,7 @@ RUN mkdir /home/node/.config && chown node:node /home/node/.config
FROM base AS app
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
COPY libraries/metrics/package.json /overleaf/libraries/metrics/package.json
@@ -32,6 +33,7 @@ COPY .yarn/patches/ /overleaf/.yarn/patches/
COPY tools/migrations/ /overleaf/tools/migrations/
RUN cd /overleaf && yarn workspaces focus @overleaf/contacts overleaf
COPY libraries/eslint-plugin/ /overleaf/libraries/eslint-plugin/
COPY libraries/fetch-utils/ /overleaf/libraries/fetch-utils/
COPY libraries/logger/ /overleaf/libraries/logger/
COPY libraries/metrics/ /overleaf/libraries/metrics/

View File

@@ -16,6 +16,7 @@ IMAGE_REPO_FINAL ?= $(IMAGE_REPO):$(BRANCH_NAME_TAG_SAFE)-$(BUILD_NUMBER)
IMAGE_CACHE ?= $(IMAGE_REPO):cache-$(shell cat \
$(MONOREPO)/package.json \
$(MONOREPO)/yarn.lock \
$(MONOREPO)/libraries/eslint-plugin/package.json \
$(MONOREPO)/libraries/fetch-utils/package.json \
$(MONOREPO)/libraries/logger/package.json \
$(MONOREPO)/libraries/metrics/package.json \

View File

@@ -19,6 +19,7 @@ RUN mkdir /home/node/.config && chown node:node /home/node/.config
FROM base AS app
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
COPY libraries/metrics/package.json /overleaf/libraries/metrics/package.json
@@ -34,6 +35,7 @@ COPY .yarn/patches/ /overleaf/.yarn/patches/
COPY tools/migrations/ /overleaf/tools/migrations/
RUN cd /overleaf && yarn workspaces focus @overleaf/docstore overleaf
COPY libraries/eslint-plugin/ /overleaf/libraries/eslint-plugin/
COPY libraries/fetch-utils/ /overleaf/libraries/fetch-utils/
COPY libraries/logger/ /overleaf/libraries/logger/
COPY libraries/metrics/ /overleaf/libraries/metrics/

View File

@@ -16,6 +16,7 @@ IMAGE_REPO_FINAL ?= $(IMAGE_REPO):$(BRANCH_NAME_TAG_SAFE)-$(BUILD_NUMBER)
IMAGE_CACHE ?= $(IMAGE_REPO):cache-$(shell cat \
$(MONOREPO)/package.json \
$(MONOREPO)/yarn.lock \
$(MONOREPO)/libraries/eslint-plugin/package.json \
$(MONOREPO)/libraries/fetch-utils/package.json \
$(MONOREPO)/libraries/logger/package.json \
$(MONOREPO)/libraries/metrics/package.json \

View File

@@ -19,6 +19,7 @@ RUN mkdir /home/node/.config && chown node:node /home/node/.config
FROM base AS app
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
COPY libraries/metrics/package.json /overleaf/libraries/metrics/package.json
@@ -35,6 +36,7 @@ COPY .yarn/patches/ /overleaf/.yarn/patches/
COPY tools/migrations/ /overleaf/tools/migrations/
RUN cd /overleaf && yarn workspaces focus @overleaf/document-updater overleaf
COPY libraries/eslint-plugin/ /overleaf/libraries/eslint-plugin/
COPY libraries/fetch-utils/ /overleaf/libraries/fetch-utils/
COPY libraries/logger/ /overleaf/libraries/logger/
COPY libraries/metrics/ /overleaf/libraries/metrics/

View File

@@ -16,6 +16,7 @@ IMAGE_REPO_FINAL ?= $(IMAGE_REPO):$(BRANCH_NAME_TAG_SAFE)-$(BUILD_NUMBER)
IMAGE_CACHE ?= $(IMAGE_REPO):cache-$(shell cat \
$(MONOREPO)/package.json \
$(MONOREPO)/yarn.lock \
$(MONOREPO)/libraries/eslint-plugin/package.json \
$(MONOREPO)/libraries/fetch-utils/package.json \
$(MONOREPO)/libraries/logger/package.json \
$(MONOREPO)/libraries/metrics/package.json \

View File

@@ -631,14 +631,14 @@ module.exports = Model = function (db, options) {
// after.
this.getOps = getOps = function (docName, start, end, callback) {
// getOps will only use the op cache if its there. It won't fill the op cache in.
if (!(start >= 0)) {
throw new Error('start must be 0+')
}
if (typeof end === 'function') {
;[end, callback] = Array.from([null, end])
}
if (!(start >= 0)) {
return callback(new Error('start must be 0+'))
}
const ops = docs[docName] != null ? docs[docName].ops : undefined
if (ops) {

View File

@@ -158,7 +158,7 @@ json.api = {
op.od = elem[key]
}
} else {
throw new Error('bad path')
return cb(new Error('bad path'))
}
return this.submitOp([op], cb)
},
@@ -166,7 +166,7 @@ json.api = {
removeAt(path, cb) {
const { elem, key } = traverse(this.snapshot, path)
if (typeof elem[key] === 'undefined') {
throw new Error('no element at that path')
return cb(new Error('no element at that path'))
}
const op = { p: path }
if (elem.constructor === Array) {
@@ -174,7 +174,7 @@ json.api = {
} else if (typeof elem === 'object') {
op.od = elem[key]
} else {
throw new Error('bad path')
return cb(new Error('bad path'))
}
return this.submitOp([op], cb)
},

View File

@@ -618,14 +618,14 @@ module.exports = Model = function (db, options) {
// after.
this.getOps = getOps = function (docName, start, end, callback) {
// getOps will only use the op cache if its there. It won't fill the op cache in.
if (!(start >= 0)) {
throw new Error('start must be 0+')
}
if (typeof end === 'function') {
;[end, callback] = Array.from([null, end])
}
if (!(start >= 0)) {
return callback(new Error('start must be 0+'))
}
const ops = docs[docName] != null ? docs[docName].ops : undefined
if (ops) {

View File

@@ -21,6 +21,7 @@ RUN mkdir /home/node/.config && chown node:node /home/node/.config
FROM base AS app
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
COPY libraries/metrics/package.json /overleaf/libraries/metrics/package.json
@@ -32,6 +33,7 @@ COPY services/filestore/package.json /overleaf/services/filestore/package.json
COPY .yarn/patches/ /overleaf/.yarn/patches/
RUN cd /overleaf && yarn workspaces focus @overleaf/filestore overleaf
COPY libraries/eslint-plugin/ /overleaf/libraries/eslint-plugin/
COPY libraries/fetch-utils/ /overleaf/libraries/fetch-utils/
COPY libraries/logger/ /overleaf/libraries/logger/
COPY libraries/metrics/ /overleaf/libraries/metrics/

View File

@@ -16,6 +16,7 @@ IMAGE_REPO_FINAL ?= $(IMAGE_REPO):$(BRANCH_NAME_TAG_SAFE)-$(BUILD_NUMBER)
IMAGE_CACHE ?= $(IMAGE_REPO):cache-$(shell cat \
$(MONOREPO)/package.json \
$(MONOREPO)/yarn.lock \
$(MONOREPO)/libraries/eslint-plugin/package.json \
$(MONOREPO)/libraries/fetch-utils/package.json \
$(MONOREPO)/libraries/logger/package.json \
$(MONOREPO)/libraries/metrics/package.json \

View File

@@ -24,6 +24,7 @@ RUN mkdir /buckets && chown node:node /buckets
FROM base AS app
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
COPY libraries/metrics/package.json /overleaf/libraries/metrics/package.json
@@ -42,6 +43,7 @@ COPY .yarn/patches/ /overleaf/.yarn/patches/
COPY tools/migrations/ /overleaf/tools/migrations/
RUN cd /overleaf && yarn workspaces focus overleaf-editor overleaf
COPY libraries/eslint-plugin/ /overleaf/libraries/eslint-plugin/
COPY libraries/fetch-utils/ /overleaf/libraries/fetch-utils/
COPY libraries/logger/ /overleaf/libraries/logger/
COPY libraries/metrics/ /overleaf/libraries/metrics/

View File

@@ -16,6 +16,7 @@ IMAGE_REPO_FINAL ?= $(IMAGE_REPO):$(BRANCH_NAME_TAG_SAFE)-$(BUILD_NUMBER)
IMAGE_CACHE ?= $(IMAGE_REPO):cache-$(shell cat \
$(MONOREPO)/package.json \
$(MONOREPO)/yarn.lock \
$(MONOREPO)/libraries/eslint-plugin/package.json \
$(MONOREPO)/libraries/fetch-utils/package.json \
$(MONOREPO)/libraries/logger/package.json \
$(MONOREPO)/libraries/metrics/package.json \

View File

@@ -19,6 +19,7 @@ RUN mkdir /home/node/.config && chown node:node /home/node/.config
FROM base AS app
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
COPY libraries/metrics/package.json /overleaf/libraries/metrics/package.json
@@ -33,6 +34,7 @@ COPY .yarn/patches/ /overleaf/.yarn/patches/
COPY tools/migrations/ /overleaf/tools/migrations/
RUN cd /overleaf && yarn workspaces focus @overleaf/notifications overleaf
COPY libraries/eslint-plugin/ /overleaf/libraries/eslint-plugin/
COPY libraries/fetch-utils/ /overleaf/libraries/fetch-utils/
COPY libraries/logger/ /overleaf/libraries/logger/
COPY libraries/metrics/ /overleaf/libraries/metrics/

View File

@@ -16,6 +16,7 @@ IMAGE_REPO_FINAL ?= $(IMAGE_REPO):$(BRANCH_NAME_TAG_SAFE)-$(BUILD_NUMBER)
IMAGE_CACHE ?= $(IMAGE_REPO):cache-$(shell cat \
$(MONOREPO)/package.json \
$(MONOREPO)/yarn.lock \
$(MONOREPO)/libraries/eslint-plugin/package.json \
$(MONOREPO)/libraries/fetch-utils/package.json \
$(MONOREPO)/libraries/logger/package.json \
$(MONOREPO)/libraries/metrics/package.json \

View File

@@ -19,6 +19,7 @@ RUN mkdir /home/node/.config && chown node:node /home/node/.config
FROM base AS app
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
COPY libraries/metrics/package.json /overleaf/libraries/metrics/package.json
@@ -36,6 +37,7 @@ COPY .yarn/patches/ /overleaf/.yarn/patches/
COPY tools/migrations/ /overleaf/tools/migrations/
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/
COPY libraries/metrics/ /overleaf/libraries/metrics/

View File

@@ -16,6 +16,7 @@ IMAGE_REPO_FINAL ?= $(IMAGE_REPO):$(BRANCH_NAME_TAG_SAFE)-$(BUILD_NUMBER)
IMAGE_CACHE ?= $(IMAGE_REPO):cache-$(shell cat \
$(MONOREPO)/package.json \
$(MONOREPO)/yarn.lock \
$(MONOREPO)/libraries/eslint-plugin/package.json \
$(MONOREPO)/libraries/fetch-utils/package.json \
$(MONOREPO)/libraries/logger/package.json \
$(MONOREPO)/libraries/metrics/package.json \

View File

@@ -77,7 +77,7 @@ export function getFileTreeDiff(projectId, fromVersion, toVersion, callback) {
if (error instanceof Errors.InconsistentChunkError) {
return callback(error)
} else {
throw OError.tag(error)
return callback(OError.tag(error))
}
}
callback(null, diff)

View File

@@ -19,6 +19,7 @@ RUN mkdir /home/node/.config && chown node:node /home/node/.config
FROM base AS app
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
COPY libraries/metrics/package.json /overleaf/libraries/metrics/package.json
@@ -31,6 +32,7 @@ COPY services/real-time/package.json /overleaf/services/real-time/package.json
COPY .yarn/patches/ /overleaf/.yarn/patches/
RUN cd /overleaf && yarn workspaces focus @overleaf/real-time overleaf
COPY libraries/eslint-plugin/ /overleaf/libraries/eslint-plugin/
COPY libraries/fetch-utils/ /overleaf/libraries/fetch-utils/
COPY libraries/logger/ /overleaf/libraries/logger/
COPY libraries/metrics/ /overleaf/libraries/metrics/

View File

@@ -16,6 +16,7 @@ IMAGE_REPO_FINAL ?= $(IMAGE_REPO):$(BRANCH_NAME_TAG_SAFE)-$(BUILD_NUMBER)
IMAGE_CACHE ?= $(IMAGE_REPO):cache-$(shell cat \
$(MONOREPO)/package.json \
$(MONOREPO)/yarn.lock \
$(MONOREPO)/libraries/eslint-plugin/package.json \
$(MONOREPO)/libraries/fetch-utils/package.json \
$(MONOREPO)/libraries/logger/package.json \
$(MONOREPO)/libraries/metrics/package.json \

View File

@@ -222,7 +222,6 @@
"@lezer/markdown": "1.6.3",
"@overleaf/codemirror-tree-view": "^0.1.3",
"@overleaf/dictionaries": "https://github.com/overleaf/dictionaries/archive/refs/tags/v0.0.3.tar.gz",
"@overleaf/eslint-plugin": "workspace:*",
"@overleaf/ranges-tracker": "workspace:*",
"@overleaf/stream-utils": "workspace:*",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.16",

View File

@@ -7259,7 +7259,6 @@ __metadata:
"@overleaf/access-token-encryptor": "workspace:*"
"@overleaf/codemirror-tree-view": "npm:^0.1.3"
"@overleaf/dictionaries": "https://github.com/overleaf/dictionaries/archive/refs/tags/v0.0.3.tar.gz"
"@overleaf/eslint-plugin": "workspace:*"
"@overleaf/fetch-utils": "workspace:*"
"@overleaf/logger": "workspace:*"
"@overleaf/metrics": "workspace:*"
@@ -22649,6 +22648,7 @@ __metadata:
"@babel/preset-env": "npm:^7.28.5"
"@babel/preset-react": "npm:^7.28.5"
"@babel/register": "npm:^7.28.3"
"@overleaf/eslint-plugin": "workspace:*"
"@overleaf/fetch-utils": "workspace:*"
"@overleaf/o-error": "workspace:*"
"@popperjs/core": "npm:^2.11.8"
@@ -25970,6 +25970,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "overleaf@workspace:."
dependencies:
"@overleaf/eslint-plugin": "workspace:*"
"@prettier/plugin-pug": "npm:^3.4.0"
"@types/chai": "npm:^4.3.0"
"@types/chai-as-promised": "npm:^7.1.8"