diff --git a/package-lock.json b/package-lock.json
index fa9436769dd..c6d2fe7d9fd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -25,6 +25,7 @@
"@types/react-dom": "^18.3.5",
"@vitest/coverage-istanbul": "^4.1.4",
"dependency-cruiser": "^17.3.10",
+ "eslint": "^9.39.4",
"happy-dom": "^20.9.0",
"prettier": "^3.8.3",
"publint": "^0.3.18",
@@ -114,21 +115,6 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
- "e2e/next-ai-kitchen-sink/node_modules/cross-spawn": {
- "version": "7.0.6",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
- "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- },
- "engines": {
- "node": ">= 8"
- }
- },
"e2e/next-ai-kitchen-sink/node_modules/eslint": {
"version": "9.26.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.26.0.tgz",
@@ -403,207 +389,6 @@
"typescript": "^5"
}
},
- "e2e/next-react-flow-kitchen-sink/node_modules/@eslint/config-array": {
- "version": "0.21.2",
- "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz",
- "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@eslint/object-schema": "^2.1.7",
- "debug": "^4.3.1",
- "minimatch": "^3.1.5"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "e2e/next-react-flow-kitchen-sink/node_modules/@eslint/config-helpers": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz",
- "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@eslint/core": "^0.17.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "e2e/next-react-flow-kitchen-sink/node_modules/@eslint/core": {
- "version": "0.17.0",
- "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz",
- "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@types/json-schema": "^7.0.15"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "e2e/next-react-flow-kitchen-sink/node_modules/@eslint/eslintrc": {
- "version": "3.3.5",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz",
- "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ajv": "^6.14.0",
- "debug": "^4.3.2",
- "espree": "^10.0.1",
- "globals": "^14.0.0",
- "ignore": "^5.2.0",
- "import-fresh": "^3.2.1",
- "js-yaml": "^4.1.1",
- "minimatch": "^3.1.5",
- "strip-json-comments": "^3.1.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "e2e/next-react-flow-kitchen-sink/node_modules/@eslint/js": {
- "version": "9.39.4",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz",
- "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://eslint.org/donate"
- }
- },
- "e2e/next-react-flow-kitchen-sink/node_modules/@eslint/plugin-kit": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz",
- "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@eslint/core": "^0.17.0",
- "levn": "^0.4.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "e2e/next-react-flow-kitchen-sink/node_modules/ajv": {
- "version": "6.14.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
- "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "e2e/next-react-flow-kitchen-sink/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "e2e/next-react-flow-kitchen-sink/node_modules/cross-spawn": {
- "version": "7.0.6",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
- "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "e2e/next-react-flow-kitchen-sink/node_modules/eslint": {
- "version": "9.39.4",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz",
- "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@eslint-community/eslint-utils": "^4.8.0",
- "@eslint-community/regexpp": "^4.12.1",
- "@eslint/config-array": "^0.21.2",
- "@eslint/config-helpers": "^0.4.2",
- "@eslint/core": "^0.17.0",
- "@eslint/eslintrc": "^3.3.5",
- "@eslint/js": "9.39.4",
- "@eslint/plugin-kit": "^0.4.1",
- "@humanfs/node": "^0.16.6",
- "@humanwhocodes/module-importer": "^1.0.1",
- "@humanwhocodes/retry": "^0.4.2",
- "@types/estree": "^1.0.6",
- "ajv": "^6.14.0",
- "chalk": "^4.0.0",
- "cross-spawn": "^7.0.6",
- "debug": "^4.3.2",
- "escape-string-regexp": "^4.0.0",
- "eslint-scope": "^8.4.0",
- "eslint-visitor-keys": "^4.2.1",
- "espree": "^10.4.0",
- "esquery": "^1.5.0",
- "esutils": "^2.0.2",
- "fast-deep-equal": "^3.1.3",
- "file-entry-cache": "^8.0.0",
- "find-up": "^5.0.0",
- "glob-parent": "^6.0.2",
- "ignore": "^5.2.0",
- "imurmurhash": "^0.1.4",
- "is-glob": "^4.0.0",
- "json-stable-stringify-without-jsonify": "^1.0.1",
- "lodash.merge": "^4.6.2",
- "minimatch": "^3.1.5",
- "natural-compare": "^1.4.0",
- "optionator": "^0.9.3"
- },
- "bin": {
- "eslint": "bin/eslint.js"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://eslint.org/donate"
- },
- "peerDependencies": {
- "jiti": "*"
- },
- "peerDependenciesMeta": {
- "jiti": {
- "optional": true
- }
- }
- },
"e2e/next-react-flow-kitchen-sink/node_modules/eslint-config-next": {
"version": "16.1.4",
"resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.1.4.tgz",
@@ -664,90 +449,6 @@
"eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
}
},
- "e2e/next-react-flow-kitchen-sink/node_modules/eslint-visitor-keys": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
- "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "e2e/next-react-flow-kitchen-sink/node_modules/espree": {
- "version": "10.4.0",
- "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
- "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "acorn": "^8.15.0",
- "acorn-jsx": "^5.3.2",
- "eslint-visitor-keys": "^4.2.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "e2e/next-react-flow-kitchen-sink/node_modules/file-entry-cache": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
- "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "flat-cache": "^4.0.0"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "e2e/next-react-flow-kitchen-sink/node_modules/flat-cache": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
- "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "flatted": "^3.2.9",
- "keyv": "^4.5.4"
- },
- "engines": {
- "node": ">=16"
- }
- },
- "e2e/next-react-flow-kitchen-sink/node_modules/globals": {
- "version": "14.0.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
- "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "e2e/next-react-flow-kitchen-sink/node_modules/minimatch": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
- "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
"e2e/next-react-flow-kitchen-sink/node_modules/react": {
"version": "19.2.3",
"resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz",
@@ -953,37 +654,6 @@
"eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
}
},
- "e2e/next-sandbox/node_modules/eslint-visitor-keys": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
- "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "e2e/next-sandbox/node_modules/espree": {
- "version": "10.4.0",
- "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
- "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "acorn": "^8.15.0",
- "acorn-jsx": "^5.3.2",
- "eslint-visitor-keys": "^4.2.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
"e2e/next-sandbox/node_modules/globals": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
@@ -2776,38 +2446,56 @@
}
},
"node_modules/@eslint/eslintrc": {
- "version": "2.1.4",
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz",
+ "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==",
"license": "MIT",
"dependencies": {
- "ajv": "^6.12.4",
+ "ajv": "^6.14.0",
"debug": "^4.3.2",
- "espree": "^9.6.0",
- "globals": "^13.19.0",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
"ignore": "^5.2.0",
"import-fresh": "^3.2.1",
- "js-yaml": "^4.1.0",
- "minimatch": "^3.1.2",
+ "js-yaml": "^4.1.1",
+ "minimatch": "^3.1.5",
"strip-json-comments": "^3.1.1"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
+ "node_modules/@eslint/eslintrc/node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/@eslint/js": {
- "version": "8.57.0",
+ "version": "9.39.4",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz",
+ "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==",
"license": "MIT",
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
}
},
"node_modules/@eslint/object-schema": {
"version": "2.1.7",
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz",
"integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==",
- "dev": true,
"license": "Apache-2.0",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -2937,7 +2625,6 @@
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
"integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
- "dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=18.18.0"
@@ -2947,7 +2634,6 @@
"version": "0.16.6",
"resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz",
"integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==",
- "dev": true,
"license": "Apache-2.0",
"dependencies": {
"@humanfs/core": "^0.19.1",
@@ -2961,7 +2647,6 @@
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz",
"integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==",
- "dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=18.18"
@@ -2971,18 +2656,6 @@
"url": "https://github.com/sponsors/nzakas"
}
},
- "node_modules/@humanwhocodes/config-array": {
- "version": "0.11.14",
- "license": "Apache-2.0",
- "dependencies": {
- "@humanwhocodes/object-schema": "^2.0.2",
- "debug": "^4.3.1",
- "minimatch": "^3.0.5"
- },
- "engines": {
- "node": ">=10.10.0"
- }
- },
"node_modules/@humanwhocodes/module-importer": {
"version": "1.0.1",
"license": "Apache-2.0",
@@ -2994,15 +2667,10 @@
"url": "https://github.com/sponsors/nzakas"
}
},
- "node_modules/@humanwhocodes/object-schema": {
- "version": "2.0.3",
- "license": "BSD-3-Clause"
- },
"node_modules/@humanwhocodes/retry": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
"integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
- "dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=18.18"
@@ -18084,79 +17752,14 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@typescript-eslint/eslint-plugin": {
- "version": "7.13.1",
- "license": "MIT",
- "dependencies": {
- "@eslint-community/regexpp": "^4.10.0",
- "@typescript-eslint/scope-manager": "7.13.1",
- "@typescript-eslint/type-utils": "7.13.1",
- "@typescript-eslint/utils": "7.13.1",
- "@typescript-eslint/visitor-keys": "7.13.1",
- "graphemer": "^1.4.0",
- "ignore": "^5.3.1",
- "natural-compare": "^1.4.0",
- "ts-api-utils": "^1.3.0"
- },
- "engines": {
- "node": "^18.18.0 || >=20.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "@typescript-eslint/parser": "^7.0.0",
- "eslint": "^8.56.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
- "version": "5.3.1",
- "license": "MIT",
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/@typescript-eslint/parser": {
- "version": "7.13.1",
- "license": "BSD-2-Clause",
- "dependencies": {
- "@typescript-eslint/scope-manager": "7.13.1",
- "@typescript-eslint/types": "7.13.1",
- "@typescript-eslint/typescript-estree": "7.13.1",
- "@typescript-eslint/visitor-keys": "7.13.1",
- "debug": "^4.3.4"
- },
- "engines": {
- "node": "^18.18.0 || >=20.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.56.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
"node_modules/@typescript-eslint/project-service": {
- "version": "8.53.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.53.1.tgz",
- "integrity": "sha512-WYC4FB5Ra0xidsmlPb+1SsnaSKPmS3gsjIARwbEkHkoWloQmuzcfypljaJcR78uyLA1h8sHdWWPHSLDI+MtNog==",
- "dev": true,
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.58.2.tgz",
+ "integrity": "sha512-Cq6UfpZZk15+r87BkIh5rDpi38W4b+Sjnb8wQCPPDDweS/LRCFjCyViEbzHk5Ck3f2QDfgmlxqSa7S7clDtlfg==",
"license": "MIT",
"dependencies": {
- "@typescript-eslint/tsconfig-utils": "^8.53.1",
- "@typescript-eslint/types": "^8.53.1",
+ "@typescript-eslint/tsconfig-utils": "^8.58.2",
+ "@typescript-eslint/types": "^8.58.2",
"debug": "^4.4.3"
},
"engines": {
@@ -18167,14 +17770,13 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "typescript": ">=4.8.4 <6.0.0"
+ "typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types": {
- "version": "8.53.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.53.1.tgz",
- "integrity": "sha512-jr/swrr2aRmUAUjW5/zQHbMaui//vQlsZcJKijZf3M26bnmLj8LyZUpj8/Rd6uzaek06OWsqdofN/Thenm5O8A==",
- "dev": true,
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.58.2.tgz",
+ "integrity": "sha512-9TukXyATBQf/Jq9AMQXfvurk+G5R2MwfqQGDR2GzGz28HvY/lXNKGhkY+6IOubwcquikWk5cjlgPvD2uAA7htQ==",
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -18188,7 +17790,6 @@
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -18202,26 +17803,10 @@
}
}
},
- "node_modules/@typescript-eslint/scope-manager": {
- "version": "7.13.1",
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/types": "7.13.1",
- "@typescript-eslint/visitor-keys": "7.13.1"
- },
- "engines": {
- "node": "^18.18.0 || >=20.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
"node_modules/@typescript-eslint/tsconfig-utils": {
- "version": "8.53.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.53.1.tgz",
- "integrity": "sha512-qfvLXS6F6b1y43pnf0pPbXJ+YoXIC7HKg0UGZ27uMIemKMKA6XH2DTxsEDdpdN29D+vHV07x/pnlPNVLhdhWiA==",
- "dev": true,
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.58.2.tgz",
+ "integrity": "sha512-3SR+RukipDvkkKp/d0jP0dyzuls3DbGmwDpVEc5wqk5f38KFThakqAAO0XMirWAE+kT00oTauTbzMFGPoAzB0A==",
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -18231,139 +17816,13 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "typescript": ">=4.8.4 <6.0.0"
- }
- },
- "node_modules/@typescript-eslint/type-utils": {
- "version": "7.13.1",
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/typescript-estree": "7.13.1",
- "@typescript-eslint/utils": "7.13.1",
- "debug": "^4.3.4",
- "ts-api-utils": "^1.3.0"
- },
- "engines": {
- "node": "^18.18.0 || >=20.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.56.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/types": {
- "version": "7.13.1",
- "license": "MIT",
- "engines": {
- "node": "^18.18.0 || >=20.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree": {
- "version": "7.13.1",
- "license": "BSD-2-Clause",
- "dependencies": {
- "@typescript-eslint/types": "7.13.1",
- "@typescript-eslint/visitor-keys": "7.13.1",
- "debug": "^4.3.4",
- "globby": "^11.1.0",
- "is-glob": "^4.0.3",
- "minimatch": "^9.0.4",
- "semver": "^7.6.0",
- "ts-api-utils": "^1.3.0"
- },
- "engines": {
- "node": "^18.18.0 || >=20.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
- "version": "2.0.1",
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
- "version": "9.0.4",
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
- "version": "7.6.2",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@typescript-eslint/utils": {
- "version": "7.13.1",
- "license": "MIT",
- "dependencies": {
- "@eslint-community/eslint-utils": "^4.4.0",
- "@typescript-eslint/scope-manager": "7.13.1",
- "@typescript-eslint/types": "7.13.1",
- "@typescript-eslint/typescript-estree": "7.13.1"
- },
- "engines": {
- "node": "^18.18.0 || >=20.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.56.0"
- }
- },
- "node_modules/@typescript-eslint/visitor-keys": {
- "version": "7.13.1",
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/types": "7.13.1",
- "eslint-visitor-keys": "^3.4.3"
- },
- "engines": {
- "node": "^18.18.0 || >=20.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
+ "typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@ungap/structured-clone": {
"version": "1.2.0",
- "license": "ISC"
+ "license": "ISC",
+ "peer": true
},
"node_modules/@vitest/coverage-istanbul": {
"version": "4.1.4",
@@ -18699,7 +18158,9 @@
}
},
"node_modules/ajv": {
- "version": "6.12.6",
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
+ "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.1",
@@ -20284,7 +19745,9 @@
}
},
"node_modules/cross-spawn": {
- "version": "7.0.3",
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
@@ -20943,16 +20406,6 @@
"redux": "^4.1.1"
}
},
- "node_modules/doctrine": {
- "version": "3.0.0",
- "license": "Apache-2.0",
- "dependencies": {
- "esutils": "^2.0.2"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
"node_modules/dom-accessibility-api": {
"version": "0.5.14",
"dev": true,
@@ -21768,56 +21221,62 @@
}
},
"node_modules/eslint": {
- "version": "8.57.0",
+ "version": "9.39.4",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz",
+ "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==",
"license": "MIT",
"dependencies": {
- "@eslint-community/eslint-utils": "^4.2.0",
- "@eslint-community/regexpp": "^4.6.1",
- "@eslint/eslintrc": "^2.1.4",
- "@eslint/js": "8.57.0",
- "@humanwhocodes/config-array": "^0.11.14",
+ "@eslint-community/eslint-utils": "^4.8.0",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.21.2",
+ "@eslint/config-helpers": "^0.4.2",
+ "@eslint/core": "^0.17.0",
+ "@eslint/eslintrc": "^3.3.5",
+ "@eslint/js": "9.39.4",
+ "@eslint/plugin-kit": "^0.4.1",
+ "@humanfs/node": "^0.16.6",
"@humanwhocodes/module-importer": "^1.0.1",
- "@nodelib/fs.walk": "^1.2.8",
- "@ungap/structured-clone": "^1.2.0",
- "ajv": "^6.12.4",
+ "@humanwhocodes/retry": "^0.4.2",
+ "@types/estree": "^1.0.6",
+ "ajv": "^6.14.0",
"chalk": "^4.0.0",
- "cross-spawn": "^7.0.2",
+ "cross-spawn": "^7.0.6",
"debug": "^4.3.2",
- "doctrine": "^3.0.0",
"escape-string-regexp": "^4.0.0",
- "eslint-scope": "^7.2.2",
- "eslint-visitor-keys": "^3.4.3",
- "espree": "^9.6.1",
- "esquery": "^1.4.2",
+ "eslint-scope": "^8.4.0",
+ "eslint-visitor-keys": "^4.2.1",
+ "espree": "^10.4.0",
+ "esquery": "^1.5.0",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
- "file-entry-cache": "^6.0.1",
+ "file-entry-cache": "^8.0.0",
"find-up": "^5.0.0",
"glob-parent": "^6.0.2",
- "globals": "^13.19.0",
- "graphemer": "^1.4.0",
"ignore": "^5.2.0",
"imurmurhash": "^0.1.4",
"is-glob": "^4.0.0",
- "is-path-inside": "^3.0.3",
- "js-yaml": "^4.1.0",
"json-stable-stringify-without-jsonify": "^1.0.1",
- "levn": "^0.4.1",
"lodash.merge": "^4.6.2",
- "minimatch": "^3.1.2",
+ "minimatch": "^3.1.5",
"natural-compare": "^1.4.0",
- "optionator": "^0.9.3",
- "strip-ansi": "^6.0.1",
- "text-table": "^0.2.0"
+ "optionator": "^0.9.3"
},
"bin": {
"eslint": "bin/eslint.js"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
- "url": "https://opencollective.com/eslint"
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
}
},
"node_modules/eslint-import-resolver-node": {
@@ -22051,14 +21510,16 @@
}
},
"node_modules/eslint-plugin-react-hooks": {
- "version": "4.6.2",
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz",
+ "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
},
"peerDependencies": {
- "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0"
+ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
}
},
"node_modules/eslint-plugin-react/node_modules/doctrine": {
@@ -22098,16 +21559,10 @@
"semver": "bin/semver.js"
}
},
- "node_modules/eslint-plugin-rulesdir": {
- "version": "0.2.2",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4.0.0"
- }
- },
"node_modules/eslint-plugin-simple-import-sort": {
- "version": "12.1.0",
+ "version": "13.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-13.0.0.tgz",
+ "integrity": "sha512-McAc+/Nlvcg4byY/CABGH8kqnefWBj8s3JA2okEtz8ixbECQgU46p0HkTUKa4YS7wvgGceimlc34p1nXqbWqtA==",
"license": "MIT",
"peerDependencies": {
"eslint": ">=5.0.0"
@@ -22117,7 +21572,6 @@
"version": "8.4.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
"integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
- "dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"esrecurse": "^4.3.0",
@@ -22140,6 +21594,57 @@
"url": "https://opencollective.com/eslint"
}
},
+ "node_modules/eslint/node_modules/@eslint/config-array": {
+ "version": "0.21.2",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz",
+ "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.7",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.5"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/eslint/node_modules/@eslint/config-helpers": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz",
+ "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.17.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/eslint/node_modules/@eslint/core": {
+ "version": "0.17.0",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz",
+ "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/eslint/node_modules/@eslint/plugin-kit": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz",
+ "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.17.0",
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
"node_modules/eslint/node_modules/chalk": {
"version": "4.1.2",
"license": "MIT",
@@ -22154,30 +21659,67 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
- "node_modules/eslint/node_modules/eslint-scope": {
- "version": "7.2.2",
- "license": "BSD-2-Clause",
- "dependencies": {
- "esrecurse": "^4.3.0",
- "estraverse": "^5.2.0"
- },
+ "node_modules/eslint/node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "license": "Apache-2.0",
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
+ "node_modules/eslint/node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/eslint/node_modules/flat-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
"node_modules/espree": {
- "version": "9.6.1",
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
+ "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
"license": "BSD-2-Clause",
"dependencies": {
- "acorn": "^8.9.0",
+ "acorn": "^8.15.0",
"acorn-jsx": "^5.3.2",
- "eslint-visitor-keys": "^3.4.1"
+ "eslint-visitor-keys": "^4.2.1"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree/node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
@@ -22678,6 +22220,7 @@
},
"node_modules/file-entry-cache": {
"version": "6.0.1",
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"flat-cache": "^3.0.4"
@@ -22902,6 +22445,7 @@
},
"node_modules/flat-cache": {
"version": "3.0.4",
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"flatted": "^3.1.0",
@@ -23369,10 +22913,6 @@
"version": "4.2.10",
"license": "ISC"
},
- "node_modules/graphemer": {
- "version": "1.4.0",
- "license": "MIT"
- },
"node_modules/graphql": {
"version": "16.8.1",
"dev": true,
@@ -24114,7 +23654,9 @@
"license": "BSD-3-Clause"
},
"node_modules/ignore": {
- "version": "5.2.4",
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
"license": "MIT",
"engines": {
"node": ">= 4"
@@ -24631,13 +24173,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/is-path-inside": {
- "version": "3.0.3",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/is-plain-obj": {
"version": "1.1.0",
"license": "MIT",
@@ -25058,7 +24593,7 @@
},
"node_modules/jiti": {
"version": "1.21.3",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"bin": {
"jiti": "bin/jiti.js"
@@ -26985,7 +26520,9 @@
}
},
"node_modules/minimatch": {
- "version": "3.1.2",
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
@@ -30435,6 +29972,7 @@
},
"node_modules/rimraf": {
"version": "3.0.2",
+ "devOptional": true,
"license": "ISC",
"dependencies": {
"glob": "^7.1.3"
@@ -32496,10 +32034,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/text-table": {
- "version": "0.2.0",
- "license": "MIT"
- },
"node_modules/thenby": {
"version": "1.3.4",
"license": "Apache-2.0"
@@ -32551,7 +32085,6 @@
"version": "0.2.16",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz",
"integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"fdir": "^6.5.0",
@@ -32568,7 +32101,6 @@
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=12.0.0"
@@ -32586,7 +32118,6 @@
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@@ -32735,16 +32266,6 @@
"url": "https://github.com/sponsors/wooorm"
}
},
- "node_modules/ts-api-utils": {
- "version": "1.3.0",
- "license": "MIT",
- "engines": {
- "node": ">=16"
- },
- "peerDependencies": {
- "typescript": ">=4.2.0"
- }
- },
"node_modules/ts-interface-checker": {
"version": "0.1.13",
"license": "Apache-2.0"
@@ -33670,16 +33191,15 @@
}
},
"node_modules/typescript-eslint": {
- "version": "8.53.1",
- "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.53.1.tgz",
- "integrity": "sha512-gB+EVQfP5RDElh9ittfXlhZJdjSU4jUSTyE2+ia8CYyNvet4ElfaLlAIqDvQV9JPknKx0jQH1racTYe/4LaLSg==",
- "dev": true,
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.58.2.tgz",
+ "integrity": "sha512-V8iSng9mRbdZjl54VJ9NKr6ZB+dW0J3TzRXRGcSbLIej9jV86ZRtlYeTKDR/QLxXykocJ5icNzbsl2+5TzIvcQ==",
"license": "MIT",
"dependencies": {
- "@typescript-eslint/eslint-plugin": "8.53.1",
- "@typescript-eslint/parser": "8.53.1",
- "@typescript-eslint/typescript-estree": "8.53.1",
- "@typescript-eslint/utils": "8.53.1"
+ "@typescript-eslint/eslint-plugin": "8.58.2",
+ "@typescript-eslint/parser": "8.58.2",
+ "@typescript-eslint/typescript-estree": "8.58.2",
+ "@typescript-eslint/utils": "8.58.2"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -33689,25 +33209,24 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <6.0.0"
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/typescript-eslint/node_modules/@typescript-eslint/eslint-plugin": {
- "version": "8.53.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.53.1.tgz",
- "integrity": "sha512-cFYYFZ+oQFi6hUnBTbLRXfTJiaQtYE3t4O692agbBl+2Zy+eqSKWtPjhPXJu1G7j4RLjKgeJPDdq3EqOwmX5Ag==",
- "dev": true,
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.58.2.tgz",
+ "integrity": "sha512-aC2qc5thQahutKjP+cl8cgN9DWe3ZUqVko30CMSZHnFEHyhOYoZSzkGtAI2mcwZ38xeImDucI4dnqsHiOYuuCw==",
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.12.2",
- "@typescript-eslint/scope-manager": "8.53.1",
- "@typescript-eslint/type-utils": "8.53.1",
- "@typescript-eslint/utils": "8.53.1",
- "@typescript-eslint/visitor-keys": "8.53.1",
+ "@typescript-eslint/scope-manager": "8.58.2",
+ "@typescript-eslint/type-utils": "8.58.2",
+ "@typescript-eslint/utils": "8.58.2",
+ "@typescript-eslint/visitor-keys": "8.58.2",
"ignore": "^7.0.5",
"natural-compare": "^1.4.0",
- "ts-api-utils": "^2.4.0"
+ "ts-api-utils": "^2.5.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -33717,22 +33236,21 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "@typescript-eslint/parser": "^8.53.1",
- "eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <6.0.0"
+ "@typescript-eslint/parser": "^8.58.2",
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/typescript-eslint/node_modules/@typescript-eslint/parser": {
- "version": "8.53.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.53.1.tgz",
- "integrity": "sha512-nm3cvFN9SqZGXjmw5bZ6cGmvJSyJPn0wU9gHAZZHDnZl2wF9PhHv78Xf06E0MaNk4zLVHL8hb2/c32XvyJOLQg==",
- "dev": true,
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.58.2.tgz",
+ "integrity": "sha512-/Zb/xaIDfxeJnvishjGdcR4jmr7S+bda8PKNhRGdljDM+elXhlvN0FyPSsMnLmJUrVG9aPO6dof80wjMawsASg==",
"license": "MIT",
"dependencies": {
- "@typescript-eslint/scope-manager": "8.53.1",
- "@typescript-eslint/types": "8.53.1",
- "@typescript-eslint/typescript-estree": "8.53.1",
- "@typescript-eslint/visitor-keys": "8.53.1",
+ "@typescript-eslint/scope-manager": "8.58.2",
+ "@typescript-eslint/types": "8.58.2",
+ "@typescript-eslint/typescript-estree": "8.58.2",
+ "@typescript-eslint/visitor-keys": "8.58.2",
"debug": "^4.4.3"
},
"engines": {
@@ -33743,19 +33261,18 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <6.0.0"
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": {
- "version": "8.53.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.53.1.tgz",
- "integrity": "sha512-Lu23yw1uJMFY8cUeq7JlrizAgeQvWugNQzJp8C3x8Eo5Jw5Q2ykMdiiTB9vBVOOUBysMzmRRmUfwFrZuI2C4SQ==",
- "dev": true,
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.58.2.tgz",
+ "integrity": "sha512-SgmyvDPexWETQek+qzZnrG6844IaO02UVyOLhI4wpo82dpZJY9+6YZCKAMFzXb7qhx37mFK1QcPQ18tud+vo6Q==",
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.53.1",
- "@typescript-eslint/visitor-keys": "8.53.1"
+ "@typescript-eslint/types": "8.58.2",
+ "@typescript-eslint/visitor-keys": "8.58.2"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -33766,17 +33283,16 @@
}
},
"node_modules/typescript-eslint/node_modules/@typescript-eslint/type-utils": {
- "version": "8.53.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.53.1.tgz",
- "integrity": "sha512-MOrdtNvyhy0rHyv0ENzub1d4wQYKb2NmIqG7qEqPWFW7Mpy2jzFC3pQ2yKDvirZB7jypm5uGjF2Qqs6OIqu47w==",
- "dev": true,
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.58.2.tgz",
+ "integrity": "sha512-Z7EloNR/B389FvabdGeTo2XMs4W9TjtPiO9DAsmT0yom0bwlPyRjkJ1uCdW1DvrrrYP50AJZ9Xc3sByZA9+dcg==",
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.53.1",
- "@typescript-eslint/typescript-estree": "8.53.1",
- "@typescript-eslint/utils": "8.53.1",
+ "@typescript-eslint/types": "8.58.2",
+ "@typescript-eslint/typescript-estree": "8.58.2",
+ "@typescript-eslint/utils": "8.58.2",
"debug": "^4.4.3",
- "ts-api-utils": "^2.4.0"
+ "ts-api-utils": "^2.5.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -33786,15 +33302,14 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <6.0.0"
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/typescript-eslint/node_modules/@typescript-eslint/types": {
- "version": "8.53.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.53.1.tgz",
- "integrity": "sha512-jr/swrr2aRmUAUjW5/zQHbMaui//vQlsZcJKijZf3M26bnmLj8LyZUpj8/Rd6uzaek06OWsqdofN/Thenm5O8A==",
- "dev": true,
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.58.2.tgz",
+ "integrity": "sha512-9TukXyATBQf/Jq9AMQXfvurk+G5R2MwfqQGDR2GzGz28HvY/lXNKGhkY+6IOubwcquikWk5cjlgPvD2uAA7htQ==",
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -33805,21 +33320,20 @@
}
},
"node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": {
- "version": "8.53.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.53.1.tgz",
- "integrity": "sha512-RGlVipGhQAG4GxV1s34O91cxQ/vWiHJTDHbXRr0li2q/BGg3RR/7NM8QDWgkEgrwQYCvmJV9ichIwyoKCQ+DTg==",
- "dev": true,
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.58.2.tgz",
+ "integrity": "sha512-ELGuoofuhhoCvNbQjFFiobFcGgcDCEm0ThWdmO4Z0UzLqPXS3KFvnEZ+SHewwOYHjM09tkzOWXNTv9u6Gqtyuw==",
"license": "MIT",
"dependencies": {
- "@typescript-eslint/project-service": "8.53.1",
- "@typescript-eslint/tsconfig-utils": "8.53.1",
- "@typescript-eslint/types": "8.53.1",
- "@typescript-eslint/visitor-keys": "8.53.1",
+ "@typescript-eslint/project-service": "8.58.2",
+ "@typescript-eslint/tsconfig-utils": "8.58.2",
+ "@typescript-eslint/types": "8.58.2",
+ "@typescript-eslint/visitor-keys": "8.58.2",
"debug": "^4.4.3",
- "minimatch": "^9.0.5",
+ "minimatch": "^10.2.2",
"semver": "^7.7.3",
"tinyglobby": "^0.2.15",
- "ts-api-utils": "^2.4.0"
+ "ts-api-utils": "^2.5.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -33829,20 +33343,19 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "typescript": ">=4.8.4 <6.0.0"
+ "typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": {
- "version": "8.53.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.53.1.tgz",
- "integrity": "sha512-c4bMvGVWW4hv6JmDUEG7fSYlWOl3II2I4ylt0NM+seinYQlZMQIaKaXIIVJWt9Ofh6whrpM+EdDQXKXjNovvrg==",
- "dev": true,
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.58.2.tgz",
+ "integrity": "sha512-QZfjHNEzPY8+l0+fIXMvuQ2sJlplB4zgDZvA+NmvZsZv3EQwOcc1DuIU1VJUTWZ/RKouBMhDyNaBMx4sWvrzRA==",
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.9.1",
- "@typescript-eslint/scope-manager": "8.53.1",
- "@typescript-eslint/types": "8.53.1",
- "@typescript-eslint/typescript-estree": "8.53.1"
+ "@typescript-eslint/scope-manager": "8.58.2",
+ "@typescript-eslint/types": "8.58.2",
+ "@typescript-eslint/typescript-estree": "8.58.2"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -33852,19 +33365,18 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <6.0.0"
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/typescript-eslint/node_modules/@typescript-eslint/visitor-keys": {
- "version": "8.53.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.53.1.tgz",
- "integrity": "sha512-oy+wV7xDKFPRyNggmXuZQSBzvoLnpmJs+GhzRhPjrxl2b/jIlyjVokzm47CZCDUdXKr2zd7ZLodPfOBpOPyPlg==",
- "dev": true,
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.58.2.tgz",
+ "integrity": "sha512-f1WO2Lx8a9t8DARmcWAUPJbu0G20bJlj8L4z72K00TMeJAoyLr/tHhI/pzYBLrR4dXWkcxO1cWYZEOX8DKHTqA==",
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.53.1",
- "eslint-visitor-keys": "^4.2.1"
+ "@typescript-eslint/types": "8.58.2",
+ "eslint-visitor-keys": "^5.0.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -33874,21 +33386,31 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
+ "node_modules/typescript-eslint/node_modules/balanced-match": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
+ "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
+ "license": "MIT",
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
"node_modules/typescript-eslint/node_modules/brace-expansion": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
- "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
- "dev": true,
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz",
+ "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==",
"license": "MIT",
"dependencies": {
- "balanced-match": "^1.0.0"
+ "balanced-match": "^4.0.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
}
},
"node_modules/typescript-eslint/node_modules/debug": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -33903,80 +33425,45 @@
}
},
"node_modules/typescript-eslint/node_modules/eslint-visitor-keys": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
- "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
- "dev": true,
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz",
+ "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==",
"license": "Apache-2.0",
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "node": "^20.19.0 || ^22.13.0 || >=24"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
- "node_modules/typescript-eslint/node_modules/fdir": {
- "version": "6.5.0",
- "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
- "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12.0.0"
- },
- "peerDependencies": {
- "picomatch": "^3 || ^4"
- },
- "peerDependenciesMeta": {
- "picomatch": {
- "optional": true
- }
- }
- },
"node_modules/typescript-eslint/node_modules/ignore": {
"version": "7.0.5",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
"integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 4"
}
},
"node_modules/typescript-eslint/node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
- "dev": true,
- "license": "ISC",
+ "version": "10.2.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
+ "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
+ "license": "BlueOak-1.0.0",
"dependencies": {
- "brace-expansion": "^2.0.1"
+ "brace-expansion": "^5.0.5"
},
"engines": {
- "node": ">=16 || 14 >=14.17"
+ "node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/typescript-eslint/node_modules/picomatch": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
"node_modules/typescript-eslint/node_modules/semver": {
- "version": "7.7.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
- "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
- "dev": true,
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -33985,28 +33472,10 @@
"node": ">=10"
}
},
- "node_modules/typescript-eslint/node_modules/tinyglobby": {
- "version": "0.2.15",
- "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
- "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fdir": "^6.5.0",
- "picomatch": "^4.0.3"
- },
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/SuperchupuDev"
- }
- },
"node_modules/typescript-eslint/node_modules/ts-api-utils": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz",
- "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==",
- "dev": true,
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz",
+ "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==",
"license": "MIT",
"engines": {
"node": ">=18.12"
@@ -36006,7 +35475,6 @@
"@liveblocks/query-parser": "^0.1.1",
"@liveblocks/vitest-config": "*",
"@types/ws": "^8.5.10",
- "eslint-plugin-rulesdir": "^0.2.2",
"fast-check": "^4.6.0",
"msw": "^2.10.4",
"ws": "^8.17.1"
@@ -36027,6 +35495,7 @@
"@liveblocks/eslint-config": "*",
"@liveblocks/vitest-config": "*",
"csstype": "3.0.2",
+ "eslint-plugin-react-hooks": "^5.2.0",
"msw": "^2.10.4"
},
"peerDependencies": {
@@ -36126,7 +35595,7 @@
"@testing-library/jest-dom": "^6.8.0",
"@testing-library/react": "^16.3.0",
"date-fns": "^3.6.0",
- "eslint-plugin-react-hooks": "^4.6.2",
+ "eslint-plugin-react-hooks": "^5.2.0",
"itertools": "^2.3.2",
"msw": "^2.10.4",
"react-error-boundary": "^4.0.13"
@@ -36165,7 +35634,7 @@
"@liveblocks/vitest-config": "*",
"@testing-library/jest-dom": "^5.16.5",
"eslint-plugin-react": "^7.33.2",
- "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-react-hooks": "^5.2.0",
"msw": "^2.10.4",
"stylelint": "^15.10.2",
"stylelint-config-standard": "^34.0.0",
@@ -36209,7 +35678,7 @@
"@testing-library/react": "^13.1.1",
"@xyflow/react": "^12.10.1",
"eslint-plugin-react": "^7.33.2",
- "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-react-hooks": "^5.2.0",
"stylelint": "^15.10.2",
"stylelint-config-standard": "^34.0.0",
"stylelint-order": "^6.0.3",
@@ -36280,7 +35749,7 @@
"@liveblocks/vitest-config": "*",
"@testing-library/jest-dom": "^5.16.5",
"eslint-plugin-react": "^7.33.2",
- "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-react-hooks": "^5.2.0",
"msw": "^2.10.4",
"stylelint": "^15.10.2",
"stylelint-config-standard": "^34.0.0",
@@ -37927,7 +37396,7 @@
"@liveblocks/vitest-config": "*",
"@testing-library/jest-dom": "^5.16.5",
"eslint-plugin-react": "^7.33.2",
- "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-react-hooks": "^5.2.0",
"msw": "^2.10.4",
"stylelint": "^15.10.2",
"stylelint-config-standard": "^34.0.0",
@@ -37978,10 +37447,6 @@
"react-dom": ">=16.8.0"
}
},
- "packages/liveblocks-react-tiptap/node_modules/@floating-ui/utils": {
- "version": "0.2.8",
- "license": "MIT"
- },
"packages/liveblocks-react-tiptap/node_modules/@radix-ui/number": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz",
@@ -39582,7 +39047,7 @@
"@testing-library/jest-dom": "^6.8.0",
"@testing-library/react": "^16.3.0",
"eslint-plugin-react": "^7.33.2",
- "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-react-hooks": "^5.2.0",
"msw": "^2.10.4",
"stylelint": "^15.10.2",
"stylelint-config-standard": "^34.0.0",
@@ -39630,10 +39095,6 @@
"react-dom": ">=16.8.0"
}
},
- "packages/liveblocks-react-ui/node_modules/@floating-ui/utils": {
- "version": "0.2.2",
- "license": "MIT"
- },
"packages/liveblocks-react-ui/node_modules/@testing-library/dom": {
"version": "10.4.1",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz",
@@ -40218,11 +39679,11 @@
"shared/eslint-config": {
"name": "@liveblocks/eslint-config",
"dependencies": {
- "@typescript-eslint/eslint-plugin": "^7.13.1",
- "@typescript-eslint/parser": "^7.13.1",
- "eslint": "^8.56.0",
- "eslint-plugin-import": "^2.29.1",
- "eslint-plugin-simple-import-sort": "^12.1.0"
+ "@eslint/js": "^9.39.4",
+ "eslint": "^9.39.4",
+ "eslint-plugin-import": "^2.32.0",
+ "eslint-plugin-simple-import-sort": "^13.0.0",
+ "typescript-eslint": "^8.58.2"
}
},
"shared/rollup-config": {
@@ -40669,9 +40130,10 @@
"yjs": "^13.6.14"
},
"devDependencies": {
+ "@liveblocks/eslint-config": "*",
"@types/webextension-polyfill": "^0.10.0",
"autoprefixer": "^10.4.13",
- "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-react-hooks": "^5.2.0",
"postcss": "^8.4.20",
"prettier-plugin-tailwindcss": "^0.5.4",
"tailwindcss": "^3.2.4",
diff --git a/package.json b/package.json
index 7fda9ab0f51..fd3d19eb412 100644
--- a/package.json
+++ b/package.json
@@ -32,6 +32,7 @@
"@types/react-dom": "^18.3.5",
"@vitest/coverage-istanbul": "^4.1.4",
"dependency-cruiser": "^17.3.10",
+ "eslint": "^9.39.4",
"happy-dom": "^20.9.0",
"prettier": "^3.8.3",
"publint": "^0.3.18",
diff --git a/packages/liveblocks-chat-sdk-adapter/.eslintrc.cjs b/packages/liveblocks-chat-sdk-adapter/.eslintrc.cjs
deleted file mode 100644
index 4fce48fbbe5..00000000000
--- a/packages/liveblocks-chat-sdk-adapter/.eslintrc.cjs
+++ /dev/null
@@ -1,9 +0,0 @@
-const commonRestrictedSyntax = require("@liveblocks/eslint-config/restricted-syntax");
-
-module.exports = {
- root: true,
- extends: ["@liveblocks/eslint-config"],
- rules: {
- "no-restricted-syntax": ["error", ...commonRestrictedSyntax],
- },
-};
diff --git a/packages/liveblocks-chat-sdk-adapter/eslint.config.mjs b/packages/liveblocks-chat-sdk-adapter/eslint.config.mjs
new file mode 100644
index 00000000000..b76be4b3cae
--- /dev/null
+++ b/packages/liveblocks-chat-sdk-adapter/eslint.config.mjs
@@ -0,0 +1,15 @@
+import { makeConfig } from "@liveblocks/eslint-config";
+import commonRestrictedSyntax from "@liveblocks/eslint-config/restricted-syntax";
+
+export default [
+ ...makeConfig(),
+
+ {
+ rules: {
+ // -------------------------------
+ // Custom syntax we want to forbid
+ // -------------------------------
+ "no-restricted-syntax": ["error", ...commonRestrictedSyntax],
+ },
+ },
+];
diff --git a/packages/liveblocks-client/.eslintrc.cjs b/packages/liveblocks-client/.eslintrc.cjs
deleted file mode 100644
index ff7df4db5a3..00000000000
--- a/packages/liveblocks-client/.eslintrc.cjs
+++ /dev/null
@@ -1,47 +0,0 @@
-const commonRestrictedSyntax = require("@liveblocks/eslint-config/restricted-syntax");
-
-module.exports = {
- root: true,
- extends: ["@liveblocks/eslint-config"],
- rules: {
- // -------------------------------
- // Custom syntax we want to forbid
- // -------------------------------
- "no-restricted-syntax": [
- "error",
- ...commonRestrictedSyntax,
- {
- selector:
- "CallExpression[callee.object.name='JSON'][callee.property.name='parse']",
- message:
- "Using `JSON.parse()` is type-unsafe. Prefer using the `tryParseJson()` utility method (from `src/utils`).",
- },
- {
- selector: "TSNonNullExpression",
- message:
- "Non-null assertions mask real problems. Please use `nn(...)` (from src/assert.ts) instead.",
- },
- ],
-
- // ----------------------------------------------------------------------
- // Overrides from default rule config used in all other projects!
- // ----------------------------------------------------------------------
- /* None yet 😇 ! */
-
- // ----------------------------------------------------------------------
- // Extra rules for this project specifically
- // ----------------------------------------------------------------------
- /* None yet 😇 ! */
- },
- overrides: [
- {
- files: ["src/__tests__/**"],
-
- // Special config for test files
- rules: {
- "no-restricted-syntax": "off",
- "@typescript-eslint/explicit-module-boundary-types": "off",
- },
- },
- ],
-};
diff --git a/packages/liveblocks-client/eslint.config.mjs b/packages/liveblocks-client/eslint.config.mjs
new file mode 100644
index 00000000000..0196f1d24fe
--- /dev/null
+++ b/packages/liveblocks-client/eslint.config.mjs
@@ -0,0 +1,49 @@
+import { makeConfig } from "@liveblocks/eslint-config";
+import commonRestrictedSyntax from "@liveblocks/eslint-config/restricted-syntax";
+
+export default [
+ ...makeConfig(),
+
+ {
+ rules: {
+ // -------------------------------
+ // Custom syntax we want to forbid
+ // -------------------------------
+ "no-restricted-syntax": [
+ "error",
+ ...commonRestrictedSyntax,
+ {
+ selector:
+ "CallExpression[callee.object.name='JSON'][callee.property.name='parse']",
+ message:
+ "Using `JSON.parse()` is type-unsafe. Prefer using the `tryParseJson()` utility method (from `src/utils`).",
+ },
+ {
+ selector: "TSNonNullExpression",
+ message:
+ "Non-null assertions mask real problems. Please use `nn(...)` (from src/assert.ts) instead.",
+ },
+ ],
+
+ // ----------------------------------------------------------------------
+ // Overrides from default rule config used in all other projects!
+ // ----------------------------------------------------------------------
+ /* None yet 😇 ! */
+
+ // ----------------------------------------------------------------------
+ // Extra rules for this project specifically
+ // ----------------------------------------------------------------------
+ /* None yet 😇 ! */
+ },
+ },
+
+ {
+ files: ["src/__tests__/**"],
+
+ // Special config for test files
+ rules: {
+ "no-restricted-syntax": "off",
+ "@typescript-eslint/explicit-module-boundary-types": "off",
+ },
+ },
+];
diff --git a/packages/liveblocks-core/.eslintrc.cjs b/packages/liveblocks-core/.eslintrc.cjs
deleted file mode 100644
index 1731674bf1f..00000000000
--- a/packages/liveblocks-core/.eslintrc.cjs
+++ /dev/null
@@ -1,65 +0,0 @@
-const commonRestrictedSyntax = require("@liveblocks/eslint-config/restricted-syntax");
-
-const rulesDirPlugin = require("eslint-plugin-rulesdir");
-rulesDirPlugin.RULES_DIR = "./rules";
-
-module.exports = {
- root: true,
- plugins: ["eslint-plugin-rulesdir"],
- extends: ["@liveblocks/eslint-config"],
- rules: {
- // -------------------------------
- // Custom syntax we want to forbid
- // -------------------------------
- "no-restricted-syntax": [
- "error",
- ...commonRestrictedSyntax,
- {
- selector:
- "CallExpression[callee.object.name='JSON'][callee.property.name='parse']",
- message:
- "Using `JSON.parse()` is type-unsafe. Prefer using the `tryParseJson()` utility method (from `src/utils`).",
- },
- {
- selector: "TSNonNullExpression",
- message:
- "Non-null assertions mask real problems. Please use `nn(...)` (from src/assert.ts) instead.",
- },
- ],
-
- // ----------------------------------------------------------------------
- // Overrides from default rule config used in all other projects!
- // ----------------------------------------------------------------------
- "@typescript-eslint/no-explicit-any": "off",
- "@typescript-eslint/no-namespace": "off",
- "@typescript-eslint/unbound-method": "off",
-
- // ----------------------------------------------------------------------
- // Extra rules for this project specifically
- // ----------------------------------------------------------------------
-
- // Always use fancy console logging (with the Liveblocks logo in there)
- "rulesdir/console-must-be-fancy": "error",
- },
- overrides: [
- {
- files: ["src/**/__tests__/**", "e2e/**"],
-
- // Special config for test files
- rules: {
- "no-restricted-syntax": "off",
- "@typescript-eslint/explicit-module-boundary-types": "off",
-
- // Ideally, we should remove these overrides, since they are still
- // useful to catch bugs
- "@typescript-eslint/no-unsafe-argument": "off",
- "@typescript-eslint/no-unsafe-assignment": "off",
- "@typescript-eslint/no-unsafe-call": "off",
- "@typescript-eslint/no-unsafe-member-access": "off",
-
- // No need for fancy console logging in tests
- "rulesdir/console-must-be-fancy": "off",
- },
- },
- ],
-};
diff --git a/packages/liveblocks-core/e2e/utils.ts b/packages/liveblocks-core/e2e/utils.ts
index fd2b665ddb5..48eb6760f00 100644
--- a/packages/liveblocks-core/e2e/utils.ts
+++ b/packages/liveblocks-core/e2e/utils.ts
@@ -74,7 +74,6 @@ async function initializeRoomForTest<
baseUrl: BASE_URL,
});
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
const { room, leave } = client.enterRoom
(roomId, {
initialPresence,
initialStorage,
diff --git a/packages/liveblocks-core/eslint.config.mjs b/packages/liveblocks-core/eslint.config.mjs
new file mode 100644
index 00000000000..1e13ad6a9ca
--- /dev/null
+++ b/packages/liveblocks-core/eslint.config.mjs
@@ -0,0 +1,81 @@
+import { makeConfig } from "@liveblocks/eslint-config";
+import commonRestrictedSyntax from "@liveblocks/eslint-config/restricted-syntax";
+
+import consoleMustBeFancy from "./rules/console-must-be-fancy.cjs";
+
+export default [
+ ...makeConfig(),
+
+ {
+ plugins: {
+ local: {
+ rules: {
+ "console-must-be-fancy": consoleMustBeFancy,
+ },
+ },
+ },
+
+ rules: {
+ // -------------------------------
+ // Custom syntax we want to forbid
+ // -------------------------------
+ "no-restricted-syntax": [
+ "error",
+ ...commonRestrictedSyntax,
+ {
+ selector:
+ "CallExpression[callee.object.name='JSON'][callee.property.name='parse']",
+ message:
+ "Using `JSON.parse()` is type-unsafe. Prefer using the `tryParseJson()` utility method (from `src/utils`).",
+ },
+ {
+ selector: "TSNonNullExpression",
+ message:
+ "Non-null assertions mask real problems. Please use `nn(...)` (from src/assert.ts) instead.",
+ },
+ ],
+
+ // ----------------------------------------------------------------------
+ // Overrides from default rule config used in all other projects!
+ // ----------------------------------------------------------------------
+ "@typescript-eslint/no-explicit-any": "off",
+ "@typescript-eslint/no-namespace": "off",
+ "@typescript-eslint/unbound-method": "off",
+
+ // TODO: New rules in typescript-eslint v8's recommendedTypeChecked
+ // that weren't in v7. Disabled during the v8 migration to keep it
+ // clean, but we should revisit and enable these later.
+ "@typescript-eslint/only-throw-error": "off",
+ "@typescript-eslint/prefer-promise-reject-errors": "off",
+ "@typescript-eslint/no-duplicate-type-constituents": "off",
+ "@typescript-eslint/no-unused-expressions": "off",
+
+ // ----------------------------------------------------------------------
+ // Extra rules for this project specifically
+ // ----------------------------------------------------------------------
+
+ // Always use fancy console logging (with the Liveblocks logo in there)
+ "local/console-must-be-fancy": "error",
+ },
+ },
+
+ {
+ files: ["src/**/__tests__/**", "e2e/**"],
+
+ // Special config for test files
+ rules: {
+ "no-restricted-syntax": "off",
+ "@typescript-eslint/explicit-module-boundary-types": "off",
+
+ // Ideally, we should remove these overrides, since they are still
+ // useful to catch bugs
+ "@typescript-eslint/no-unsafe-argument": "off",
+ "@typescript-eslint/no-unsafe-assignment": "off",
+ "@typescript-eslint/no-unsafe-call": "off",
+ "@typescript-eslint/no-unsafe-member-access": "off",
+
+ // No need for fancy console logging in tests
+ "local/console-must-be-fancy": "off",
+ },
+ },
+];
diff --git a/packages/liveblocks-core/package.json b/packages/liveblocks-core/package.json
index 163854f98f0..a100284a783 100644
--- a/packages/liveblocks-core/package.json
+++ b/packages/liveblocks-core/package.json
@@ -53,7 +53,6 @@
"@liveblocks/query-parser": "^0.1.1",
"@liveblocks/vitest-config": "*",
"@types/ws": "^8.5.10",
- "eslint-plugin-rulesdir": "^0.2.2",
"fast-check": "^4.6.0",
"msw": "^2.10.4",
"ws": "^8.17.1"
diff --git a/packages/liveblocks-core/src/devtools/bridge.ts b/packages/liveblocks-core/src/devtools/bridge.ts
index 17c16cf9742..ad46b9d3ee5 100644
--- a/packages/liveblocks-core/src/devtools/bridge.ts
+++ b/packages/liveblocks-core/src/devtools/bridge.ts
@@ -32,7 +32,7 @@ export function sendToPanel(
if (!(options?.force || _bridgeActive)) {
/*
- // eslint-disable-next-line rulesdir/console-must-be-fancy
+ // eslint-disable-next-line local/console-must-be-fancy
console.log(
"%c[client → panel] %c%s",
"color: green",
@@ -44,7 +44,7 @@ export function sendToPanel(
return;
}
/*
- // eslint-disable-next-line rulesdir/console-must-be-fancy
+ // eslint-disable-next-line local/console-must-be-fancy
console.log(
"%c[client → panel] %c%s",
"color: green",
diff --git a/packages/liveblocks-core/src/dupe-detection.ts b/packages/liveblocks-core/src/dupe-detection.ts
index 80e8476c3a1..eb5e2341069 100644
--- a/packages/liveblocks-core/src/dupe-detection.ts
+++ b/packages/liveblocks-core/src/dupe-detection.ts
@@ -16,7 +16,7 @@ const SPACE = " "; // Important space to make sure links in errors are clickable
function error(msg: string): void {
if (process.env.NODE_ENV === "production") {
- // eslint-disable-next-line rulesdir/console-must-be-fancy
+ // eslint-disable-next-line local/console-must-be-fancy
console.error(msg);
} else {
throw new Error(msg);
diff --git a/packages/liveblocks-core/src/lib/__tests__/signals/Signal.test.ts b/packages/liveblocks-core/src/lib/__tests__/signals/Signal.test.ts
index 62ffb66e429..96e4e27c062 100644
--- a/packages/liveblocks-core/src/lib/__tests__/signals/Signal.test.ts
+++ b/packages/liveblocks-core/src/lib/__tests__/signals/Signal.test.ts
@@ -134,7 +134,6 @@ test("[prop] will freeze all given values", () => {
const signal = new Signal(init);
expect(signal.get()).toBe(init);
- /* eslint-disable @typescript-eslint/no-unsafe-return */
expect(() => {
// @ts-expect-error - deliberately set invalid prop
signal.get().abc = 123;
@@ -153,7 +152,6 @@ test("[prop] will freeze all given values", () => {
// @ts-expect-error - get prop
expect(signal.get().xyz).toBe(undefined);
- /* eslint-enable @typescript-eslint/no-unsafe-return */
}
)
);
diff --git a/packages/liveblocks-core/src/lib/fancy-console.ts b/packages/liveblocks-core/src/lib/fancy-console.ts
index 5f2c1a22e4e..a1358b0606e 100644
--- a/packages/liveblocks-core/src/lib/fancy-console.ts
+++ b/packages/liveblocks-core/src/lib/fancy-console.ts
@@ -1,4 +1,4 @@
-/* eslint-disable rulesdir/console-must-be-fancy */
+/* eslint-disable local/console-must-be-fancy */
const badge =
"background:#0e0d12;border-radius:9999px;color:#fff;padding:3px 7px;font-family:sans-serif;font-weight:600;";
diff --git a/packages/liveblocks-core/src/lib/stringify.ts b/packages/liveblocks-core/src/lib/stringify.ts
index 60ae3ae5b31..0a4ea891cc3 100644
--- a/packages/liveblocks-core/src/lib/stringify.ts
+++ b/packages/liveblocks-core/src/lib/stringify.ts
@@ -1,6 +1,4 @@
-/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
-/* eslint-disable @typescript-eslint/no-unsafe-argument */
function replacer(_key: string, value: unknown) {
return value !== null && typeof value === "object" && !Array.isArray(value)
@@ -30,10 +28,10 @@ export function stringifyOrLog(value: unknown): string {
try {
return JSON.stringify(value);
} catch (err) {
- /* eslint-disable rulesdir/console-must-be-fancy */
+ /* eslint-disable local/console-must-be-fancy */
console.error(`Could not stringify: ${(err as Error).message}`);
console.error(value);
- /* eslint-enable rulesdir/console-must-be-fancy */
+ /* eslint-enable local/console-must-be-fancy */
throw err;
}
}
diff --git a/packages/liveblocks-core/src/types/InferFromSchema.ts b/packages/liveblocks-core/src/types/InferFromSchema.ts
index 11f482428b3..1dfe4fb1906 100644
--- a/packages/liveblocks-core/src/types/InferFromSchema.ts
+++ b/packages/liveblocks-core/src/types/InferFromSchema.ts
@@ -5,7 +5,7 @@ import type { Resolve } from "../lib/Resolve";
export type JSONObjectSchema7 = JSONSchema7 & { type: "object" };
-// eslint-disable-next-line @typescript-eslint/ban-types
+// eslint-disable-next-line @typescript-eslint/no-empty-object-type
type NoFields = {};
type Infer = T extends JSONSchema7 ? InferFromSchema : never;
diff --git a/packages/liveblocks-core/src/types/KnownKeys.ts b/packages/liveblocks-core/src/types/KnownKeys.ts
index 7fa2e003e43..26949439bd1 100644
--- a/packages/liveblocks-core/src/types/KnownKeys.ts
+++ b/packages/liveblocks-core/src/types/KnownKeys.ts
@@ -3,7 +3,7 @@
* any index signature (e.g. `[key: string]: ...`).
*/
export type KnownKeys = keyof {
- // eslint-disable-next-line @typescript-eslint/ban-types
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
[K in keyof T as {} extends Record ? never : K]: true;
} &
string;
diff --git a/packages/liveblocks-core/src/types/LiveblocksError.ts b/packages/liveblocks-core/src/types/LiveblocksError.ts
index 24231467aa4..0fc0bcbeca4 100644
--- a/packages/liveblocks-core/src/types/LiveblocksError.ts
+++ b/packages/liveblocks-core/src/types/LiveblocksError.ts
@@ -7,12 +7,12 @@ import type { Patchable } from "./Patchable";
type AiConnectionErrorContext = {
type: "AI_CONNECTION_ERROR";
- code: -1 | 4001 | (number & {}); // eslint-disable-line @typescript-eslint/ban-types
+ code: -1 | 4001 | (number & {});
};
type RoomConnectionErrorContext = {
type: "ROOM_CONNECTION_ERROR";
- code: -1 | 4001 | 4005 | 4006 | (number & {}); // eslint-disable-line @typescript-eslint/ban-types
+ code: -1 | 4001 | 4005 | 4006 | (number & {});
roomId: string;
};
diff --git a/packages/liveblocks-emails/.eslintrc.cjs b/packages/liveblocks-emails/.eslintrc.cjs
deleted file mode 100644
index 757c394e461..00000000000
--- a/packages/liveblocks-emails/.eslintrc.cjs
+++ /dev/null
@@ -1,25 +0,0 @@
-const commonRestrictedSyntax = require("@liveblocks/eslint-config/restricted-syntax");
-
-module.exports = {
- root: true,
- extends: ["@liveblocks/eslint-config"],
- plugins: ["react-hooks"],
- rules: {
- // -------------------------------
- // Custom syntax we want to forbid
- // -------------------------------
- "no-restricted-syntax": [
- "error",
- ...commonRestrictedSyntax,
- {
- selector:
- "ImportDeclaration[source.value='react'] ImportSpecifier[imported.name='use']",
- message: "use is only available on React >=19.",
- },
- ],
-
- // Enforce React best practices
- "react-hooks/rules-of-hooks": "error",
- "react-hooks/exhaustive-deps": "error",
- },
-};
diff --git a/packages/liveblocks-emails/eslint.config.mjs b/packages/liveblocks-emails/eslint.config.mjs
new file mode 100644
index 00000000000..143ac76c20c
--- /dev/null
+++ b/packages/liveblocks-emails/eslint.config.mjs
@@ -0,0 +1,32 @@
+import { makeConfig } from "@liveblocks/eslint-config";
+import commonRestrictedSyntax from "@liveblocks/eslint-config/restricted-syntax";
+import reactHooks from "eslint-plugin-react-hooks";
+
+export default [
+ ...makeConfig(),
+
+ {
+ plugins: {
+ "react-hooks": reactHooks,
+ },
+
+ rules: {
+ // -------------------------------
+ // Custom syntax we want to forbid
+ // -------------------------------
+ "no-restricted-syntax": [
+ "error",
+ ...commonRestrictedSyntax,
+ {
+ selector:
+ "ImportDeclaration[source.value='react'] ImportSpecifier[imported.name='use']",
+ message: "use is only available on React >=19.",
+ },
+ ],
+
+ // Enforce React best practices
+ "react-hooks/rules-of-hooks": "error",
+ "react-hooks/exhaustive-deps": "error",
+ },
+ },
+];
diff --git a/packages/liveblocks-emails/package.json b/packages/liveblocks-emails/package.json
index 5e1bb34483e..74913eb358a 100644
--- a/packages/liveblocks-emails/package.json
+++ b/packages/liveblocks-emails/package.json
@@ -56,6 +56,7 @@
"@liveblocks/eslint-config": "*",
"@liveblocks/vitest-config": "*",
"csstype": "3.0.2",
+ "eslint-plugin-react-hooks": "^5.2.0",
"msw": "^2.10.4"
},
"sideEffects": false,
diff --git a/packages/liveblocks-emails/src/lib/__tests__/css-properties.test.ts b/packages/liveblocks-emails/src/lib/__tests__/css-properties.test.ts
index 1a7b7e37d75..cc0cea68b6a 100644
--- a/packages/liveblocks-emails/src/lib/__tests__/css-properties.test.ts
+++ b/packages/liveblocks-emails/src/lib/__tests__/css-properties.test.ts
@@ -66,11 +66,9 @@ describe("to inline css string", () => {
test("should ignore null, undefined, and boolean values", () => {
const styles: CSSProperties = {
color: "red",
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error - `null` is not a legal value, try to use it anyway
backgroundColor: null,
display: undefined,
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error - `true` is not a legal value, try to use it anyway
visibility: true,
opacity: 0.5,
diff --git a/packages/liveblocks-node-lexical/.eslintrc.cjs b/packages/liveblocks-node-lexical/.eslintrc.cjs
deleted file mode 100644
index ae2147270af..00000000000
--- a/packages/liveblocks-node-lexical/.eslintrc.cjs
+++ /dev/null
@@ -1,12 +0,0 @@
-const commonRestrictedSyntax = require("@liveblocks/eslint-config/restricted-syntax");
-
-module.exports = {
- root: true,
- extends: ["@liveblocks/eslint-config"],
- rules: {
- // -------------------------------
- // Custom syntax we want to forbid
- // -------------------------------
- "no-restricted-syntax": ["error", ...commonRestrictedSyntax],
- },
-};
diff --git a/packages/liveblocks-node-lexical/eslint.config.mjs b/packages/liveblocks-node-lexical/eslint.config.mjs
new file mode 100644
index 00000000000..b76be4b3cae
--- /dev/null
+++ b/packages/liveblocks-node-lexical/eslint.config.mjs
@@ -0,0 +1,15 @@
+import { makeConfig } from "@liveblocks/eslint-config";
+import commonRestrictedSyntax from "@liveblocks/eslint-config/restricted-syntax";
+
+export default [
+ ...makeConfig(),
+
+ {
+ rules: {
+ // -------------------------------
+ // Custom syntax we want to forbid
+ // -------------------------------
+ "no-restricted-syntax": ["error", ...commonRestrictedSyntax],
+ },
+ },
+];
diff --git a/packages/liveblocks-node-prosemirror/.eslintrc.cjs b/packages/liveblocks-node-prosemirror/.eslintrc.cjs
deleted file mode 100644
index ae2147270af..00000000000
--- a/packages/liveblocks-node-prosemirror/.eslintrc.cjs
+++ /dev/null
@@ -1,12 +0,0 @@
-const commonRestrictedSyntax = require("@liveblocks/eslint-config/restricted-syntax");
-
-module.exports = {
- root: true,
- extends: ["@liveblocks/eslint-config"],
- rules: {
- // -------------------------------
- // Custom syntax we want to forbid
- // -------------------------------
- "no-restricted-syntax": ["error", ...commonRestrictedSyntax],
- },
-};
diff --git a/packages/liveblocks-node-prosemirror/eslint.config.mjs b/packages/liveblocks-node-prosemirror/eslint.config.mjs
new file mode 100644
index 00000000000..b76be4b3cae
--- /dev/null
+++ b/packages/liveblocks-node-prosemirror/eslint.config.mjs
@@ -0,0 +1,15 @@
+import { makeConfig } from "@liveblocks/eslint-config";
+import commonRestrictedSyntax from "@liveblocks/eslint-config/restricted-syntax";
+
+export default [
+ ...makeConfig(),
+
+ {
+ rules: {
+ // -------------------------------
+ // Custom syntax we want to forbid
+ // -------------------------------
+ "no-restricted-syntax": ["error", ...commonRestrictedSyntax],
+ },
+ },
+];
diff --git a/packages/liveblocks-node-prosemirror/src/document.ts b/packages/liveblocks-node-prosemirror/src/document.ts
index 2b61e877b92..bc63ba09240 100644
--- a/packages/liveblocks-node-prosemirror/src/document.ts
+++ b/packages/liveblocks-node-prosemirror/src/document.ts
@@ -182,7 +182,7 @@ export async function withProsemirrorDocument(
}
const node = createDocumentFromContent(content, schema);
if (!node) {
- throw "Invalid content";
+ throw new Error("Invalid content");
}
return this.update((doc, tr) => {
tr.delete(0, doc.content.size);
diff --git a/packages/liveblocks-node/.eslintrc.cjs b/packages/liveblocks-node/.eslintrc.cjs
deleted file mode 100644
index ae2147270af..00000000000
--- a/packages/liveblocks-node/.eslintrc.cjs
+++ /dev/null
@@ -1,12 +0,0 @@
-const commonRestrictedSyntax = require("@liveblocks/eslint-config/restricted-syntax");
-
-module.exports = {
- root: true,
- extends: ["@liveblocks/eslint-config"],
- rules: {
- // -------------------------------
- // Custom syntax we want to forbid
- // -------------------------------
- "no-restricted-syntax": ["error", ...commonRestrictedSyntax],
- },
-};
diff --git a/packages/liveblocks-node/eslint.config.mjs b/packages/liveblocks-node/eslint.config.mjs
new file mode 100644
index 00000000000..b76be4b3cae
--- /dev/null
+++ b/packages/liveblocks-node/eslint.config.mjs
@@ -0,0 +1,15 @@
+import { makeConfig } from "@liveblocks/eslint-config";
+import commonRestrictedSyntax from "@liveblocks/eslint-config/restricted-syntax";
+
+export default [
+ ...makeConfig(),
+
+ {
+ rules: {
+ // -------------------------------
+ // Custom syntax we want to forbid
+ // -------------------------------
+ "no-restricted-syntax": ["error", ...commonRestrictedSyntax],
+ },
+ },
+];
diff --git a/packages/liveblocks-node/src/utils.ts b/packages/liveblocks-node/src/utils.ts
index f9d9f916dfa..065237114ed 100644
--- a/packages/liveblocks-node/src/utils.ts
+++ b/packages/liveblocks-node/src/utils.ts
@@ -3,7 +3,7 @@ const DEFAULT_BASE_URL = "https://api.liveblocks.io";
// Valid alphabet for secret/public keys
const VALID_KEY_CHARS_REGEX = /^[\w-]+$/;
-export function getBaseUrl(baseUrl?: string | undefined): string {
+export function getBaseUrl(baseUrl?: string): string {
if (
typeof baseUrl === "string" &&
baseUrl.startsWith("http") // Must be http or https URL
diff --git a/packages/liveblocks-react-blocknote/.eslintrc.cjs b/packages/liveblocks-react-blocknote/.eslintrc.cjs
deleted file mode 100644
index f2ebc3e9fd9..00000000000
--- a/packages/liveblocks-react-blocknote/.eslintrc.cjs
+++ /dev/null
@@ -1,76 +0,0 @@
-const commonRestrictedSyntax = require("@liveblocks/eslint-config/restricted-syntax");
-
-module.exports = {
- root: true,
- extends: ["@liveblocks/eslint-config"],
- plugins: ["react", "react-hooks"],
- parserOptions: {
- ecmaFeatures: {
- jsx: true,
- },
- },
- settings: {
- react: {
- version: "detect",
- },
- },
- rules: {
- // -------------------------------
- // Custom syntax we want to forbid
- // -------------------------------
- "no-restricted-syntax": [
- "error",
- ...commonRestrictedSyntax,
- {
- selector:
- "ImportDeclaration[source.value='react'] ImportSpecifier[imported.name='use']",
- message: "use is only available on React >=19.",
- },
- ],
-
- // ----------------------------------------------------------------------
- // Overrides from default rule config used in all other projects!
- // ----------------------------------------------------------------------
- "@typescript-eslint/no-explicit-any": "off",
- "@typescript-eslint/no-non-null-assertion": "off",
- "@typescript-eslint/explicit-module-boundary-types": "off",
- "@typescript-eslint/unbound-method": "off",
-
- // ----------------------------------------------------------------------
- // Extra rules for this project specifically
- // ----------------------------------------------------------------------
-
- // Enforce React best practices
- "react-hooks/rules-of-hooks": "error",
- "react-hooks/exhaustive-deps": "error",
- "react/jsx-key": ["error", { checkFragmentShorthand: true }],
- "react/no-unescaped-entities": "error",
- "react/no-unknown-property": "error",
-
- // Relax promise rules given how we use them in this project
- "@typescript-eslint/no-floating-promises": "off",
- "@typescript-eslint/no-misused-promises": "off",
- },
-
- overrides: [
- {
- files: ["src/**/__tests__/**"],
-
- rules: {
- // Ideally, enable these lint rules again later, as they are useful to
- // catch bugs
- "@typescript-eslint/no-unsafe-argument": "off",
- "@typescript-eslint/no-unsafe-assignment": "off",
- "@typescript-eslint/no-unsafe-return": "off",
- "@typescript-eslint/unbound-method": "off",
- "@typescript-eslint/no-floating-promises": "off",
- },
- },
- {
- files: ["rollup.config.mjs"],
- env: {
- node: true,
- },
- },
- ],
-};
diff --git a/packages/liveblocks-react-blocknote/eslint.config.mjs b/packages/liveblocks-react-blocknote/eslint.config.mjs
new file mode 100644
index 00000000000..0e45a93e9d4
--- /dev/null
+++ b/packages/liveblocks-react-blocknote/eslint.config.mjs
@@ -0,0 +1,73 @@
+import { makeConfig } from "@liveblocks/eslint-config";
+import commonRestrictedSyntax from "@liveblocks/eslint-config/restricted-syntax";
+import react from "eslint-plugin-react";
+import reactHooks from "eslint-plugin-react-hooks";
+
+export default [
+ ...makeConfig(),
+
+ {
+ plugins: {
+ react,
+ "react-hooks": reactHooks,
+ },
+
+ settings: {
+ react: {
+ version: "detect",
+ },
+ },
+
+ rules: {
+ // -------------------------------
+ // Custom syntax we want to forbid
+ // -------------------------------
+ "no-restricted-syntax": [
+ "error",
+ ...commonRestrictedSyntax,
+ {
+ selector:
+ "ImportDeclaration[source.value='react'] ImportSpecifier[imported.name='use']",
+ message: "use is only available on React >=19.",
+ },
+ ],
+
+ // ----------------------------------------------------------------------
+ // Overrides from default rule config used in all other projects!
+ // ----------------------------------------------------------------------
+ "@typescript-eslint/no-explicit-any": "off",
+ "@typescript-eslint/no-non-null-assertion": "off",
+ "@typescript-eslint/explicit-module-boundary-types": "off",
+ "@typescript-eslint/unbound-method": "off",
+
+ // ----------------------------------------------------------------------
+ // Extra rules for this project specifically
+ // ----------------------------------------------------------------------
+
+ // Enforce React best practices
+ "react-hooks/rules-of-hooks": "error",
+ "react-hooks/exhaustive-deps": "error",
+ "react/jsx-key": ["error", { checkFragmentShorthand: true }],
+ "react/no-unescaped-entities": "error",
+ "react/no-unknown-property": "error",
+
+ // Relax promise rules given how we use them in this project
+ "@typescript-eslint/no-floating-promises": "off",
+ "@typescript-eslint/no-misused-promises": "off",
+ },
+ },
+
+ {
+ files: ["src/**/__tests__/**"],
+
+ rules: {
+ // Ideally, enable these lint rules again later, as they are useful to
+ // catch bugs
+ "@typescript-eslint/no-unsafe-argument": "off",
+ "@typescript-eslint/no-unsafe-assignment": "off",
+ "@typescript-eslint/no-unsafe-return": "off",
+ "@typescript-eslint/unbound-method": "off",
+ "@typescript-eslint/no-floating-promises": "off",
+ },
+ },
+];
diff --git a/packages/liveblocks-react-blocknote/package.json b/packages/liveblocks-react-blocknote/package.json
index 8451023db02..a88e5d5c598 100644
--- a/packages/liveblocks-react-blocknote/package.json
+++ b/packages/liveblocks-react-blocknote/package.json
@@ -76,7 +76,7 @@
"@liveblocks/rollup-config": "*",
"@testing-library/jest-dom": "^5.16.5",
"eslint-plugin-react": "^7.33.2",
- "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-react-hooks": "^5.2.0",
"msw": "^2.10.4",
"stylelint": "^15.10.2",
"stylelint-config-standard": "^34.0.0",
diff --git a/packages/liveblocks-react-blocknote/src/initialization/liveblocksEditorOptions.ts b/packages/liveblocks-react-blocknote/src/initialization/liveblocksEditorOptions.ts
index 767acb5feb4..3b207c863f5 100644
--- a/packages/liveblocks-react-blocknote/src/initialization/liveblocksEditorOptions.ts
+++ b/packages/liveblocks-react-blocknote/src/initialization/liveblocksEditorOptions.ts
@@ -20,7 +20,6 @@ export const withLiveblocksEditorOptions = <
S extends StyleSchema = DefaultStyleSchema,
>(
liveblocksExtension: Extension,
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
blocknoteOptions: Partial> = {},
liveblocksOptions: Partial<{ mentions: boolean }> = {}
): Partial> => {
@@ -37,7 +36,6 @@ export const withLiveblocksEditorOptions = <
// add the liveblocks extension
extensions: [
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
createExtension({
key: "liveblocksExtension",
tiptapExtensions: [liveblocksExtension],
diff --git a/packages/liveblocks-react-flow/.eslintrc.cjs b/packages/liveblocks-react-flow/.eslintrc.cjs
deleted file mode 100644
index ec54ae38f96..00000000000
--- a/packages/liveblocks-react-flow/.eslintrc.cjs
+++ /dev/null
@@ -1,62 +0,0 @@
-const commonRestrictedSyntax = require("@liveblocks/eslint-config/restricted-syntax");
-
-module.exports = {
- root: true,
- extends: ["@liveblocks/eslint-config"],
- plugins: ["react-hooks"],
- rules: {
- // -------------------------------
- // Custom syntax we want to forbid
- // -------------------------------
- "no-restricted-syntax": [
- "error",
- ...commonRestrictedSyntax,
- {
- selector:
- "ImportDeclaration[source.value='react'] ImportSpecifier[imported.name='use']",
- message: "use is only available on React >=19.",
- },
- {
- selector:
- "ImportDeclaration[source.value='react'] ImportSpecifier[imported.name='useLayoutEffect']",
- message:
- "useLayoutEffect triggers a warning when executed on the server on React <=18.2.0. Import it from './lib/use-layout-effect' instead.",
- },
- ],
-
- // ----------------------------------------------------------------------
- // Overrides from default rule config used in all other projects!
- // ----------------------------------------------------------------------
- "@typescript-eslint/no-explicit-any": "off",
- "@typescript-eslint/no-non-null-assertion": "off",
- "@typescript-eslint/explicit-module-boundary-types": "off",
- "@typescript-eslint/unbound-method": "off",
-
- // ----------------------------------------------------------------------
- // Extra rules for this project specifically
- // ----------------------------------------------------------------------
-
- // Enforce React best practices
- "react-hooks/rules-of-hooks": "error",
- "react-hooks/exhaustive-deps": [
- "error",
- { additionalHooks: "useMutation" },
- ],
- },
-
- overrides: [
- {
- files: ["src/**/__tests__/**"],
-
- rules: {
- // Ideally, enable these lint rules again later, as they are useful to
- // catch bugs
- "@typescript-eslint/no-unsafe-argument": "off",
- "@typescript-eslint/no-unsafe-assignment": "off",
- "@typescript-eslint/no-unsafe-return": "off",
- "@typescript-eslint/unbound-method": "off",
- "@typescript-eslint/no-floating-promises": "off",
- },
- },
- ],
-};
diff --git a/packages/liveblocks-react-flow/eslint.config.mjs b/packages/liveblocks-react-flow/eslint.config.mjs
new file mode 100644
index 00000000000..2d227d94c4c
--- /dev/null
+++ b/packages/liveblocks-react-flow/eslint.config.mjs
@@ -0,0 +1,67 @@
+import { makeConfig } from "@liveblocks/eslint-config";
+import commonRestrictedSyntax from "@liveblocks/eslint-config/restricted-syntax";
+import reactHooks from "eslint-plugin-react-hooks";
+
+export default [
+ ...makeConfig(),
+
+ {
+ plugins: {
+ "react-hooks": reactHooks,
+ },
+
+ rules: {
+ // -------------------------------
+ // Custom syntax we want to forbid
+ // -------------------------------
+ "no-restricted-syntax": [
+ "error",
+ ...commonRestrictedSyntax,
+ {
+ selector:
+ "ImportDeclaration[source.value='react'] ImportSpecifier[imported.name='use']",
+ message: "use is only available on React >=19.",
+ },
+ {
+ selector:
+ "ImportDeclaration[source.value='react'] ImportSpecifier[imported.name='useLayoutEffect']",
+ message:
+ "useLayoutEffect triggers a warning when executed on the server on React <=18.2.0. Import it from './lib/use-layout-effect' instead.",
+ },
+ ],
+
+ // ----------------------------------------------------------------------
+ // Overrides from default rule config used in all other projects!
+ // ----------------------------------------------------------------------
+ "@typescript-eslint/no-explicit-any": "off",
+ "@typescript-eslint/no-non-null-assertion": "off",
+ "@typescript-eslint/explicit-module-boundary-types": "off",
+ "@typescript-eslint/unbound-method": "off",
+
+ // ----------------------------------------------------------------------
+ // Extra rules for this project specifically
+ // ----------------------------------------------------------------------
+
+ // Enforce React best practices
+ "react-hooks/rules-of-hooks": "error",
+ "react-hooks/exhaustive-deps": [
+ "error",
+ { additionalHooks: "useMutation" },
+ ],
+ },
+ },
+
+ {
+ files: ["src/**/__tests__/**"],
+
+ rules: {
+ // Ideally, enable these lint rules again later, as they are useful to
+ // catch bugs
+ "@typescript-eslint/no-unsafe-argument": "off",
+ "@typescript-eslint/no-unsafe-assignment": "off",
+ "@typescript-eslint/no-unsafe-return": "off",
+ "@typescript-eslint/unbound-method": "off",
+ "@typescript-eslint/no-floating-promises": "off",
+ },
+ },
+];
diff --git a/packages/liveblocks-react-flow/package.json b/packages/liveblocks-react-flow/package.json
index 0c8fe1d6b83..2507e6905c1 100644
--- a/packages/liveblocks-react-flow/package.json
+++ b/packages/liveblocks-react-flow/package.json
@@ -90,7 +90,7 @@
"@testing-library/react": "^13.1.1",
"@xyflow/react": "^12.10.1",
"eslint-plugin-react": "^7.33.2",
- "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-react-hooks": "^5.2.0",
"stylelint": "^15.10.2",
"stylelint-config-standard": "^34.0.0",
"stylelint-order": "^6.0.3",
diff --git a/packages/liveblocks-react-flow/src/lib/types.ts b/packages/liveblocks-react-flow/src/lib/types.ts
index 9991f19fe47..6a3199547bb 100644
--- a/packages/liveblocks-react-flow/src/lib/types.ts
+++ b/packages/liveblocks-react-flow/src/lib/types.ts
@@ -21,10 +21,7 @@ type InferNodeTypeLiterals =
: T
: never;
-type NodeTypeLiterals =
- | (string & {}) // eslint-disable-line @typescript-eslint/ban-types
- | "*"
- | InferNodeTypeLiterals;
+type NodeTypeLiterals = (string & {}) | "*" | InferNodeTypeLiterals;
type InferEdgeTypeLiterals =
E extends Edge
@@ -33,10 +30,7 @@ type InferEdgeTypeLiterals =
: T
: never;
-type EdgeTypeLiterals =
- | (string & {}) // eslint-disable-line @typescript-eslint/ban-types
- | "*"
- | InferEdgeTypeLiterals;
+type EdgeTypeLiterals = (string & {}) | "*" | InferEdgeTypeLiterals;
export type NodeSyncConfig = {
[key in NodeTypeLiterals]?: SyncConfig;
@@ -63,7 +57,7 @@ type ToLson =
[S] extends [false] ? T | undefined :
[S] extends ["atomic"] ? T :
T extends JsonScalar ? T :
- // eslint-disable-next-line @typescript-eslint/ban-types
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
T extends Date | RegExp | Function | Promise | WeakMap | WeakSet | Map | Set ? never :
T extends ReadonlyArray ? ToLiveList :
T extends object ? ToLiveObject :
diff --git a/packages/liveblocks-react-lexical/.eslintrc.cjs b/packages/liveblocks-react-lexical/.eslintrc.cjs
deleted file mode 100644
index 958303bf03e..00000000000
--- a/packages/liveblocks-react-lexical/.eslintrc.cjs
+++ /dev/null
@@ -1,76 +0,0 @@
-const commonRestrictedSyntax = require("@liveblocks/eslint-config/restricted-syntax");
-
-module.exports = {
- root: true,
- extends: ["@liveblocks/eslint-config"],
- plugins: ["react", "react-hooks"],
- parserOptions: {
- ecmaFeatures: {
- jsx: true,
- },
- },
- settings: {
- react: {
- version: "detect",
- },
- },
- rules: {
- // -------------------------------
- // Custom syntax we want to forbid
- // -------------------------------
- "no-restricted-syntax": [
- "error",
- ...commonRestrictedSyntax,
- {
- selector:
- "ImportDeclaration[source.value='react'] ImportSpecifier[imported.name='use']",
- message: "use is only available on React >=19.",
- },
- ],
-
- // ----------------------------------------------------------------------
- // Overrides from default rule config used in all other projects!
- // ----------------------------------------------------------------------
- "@typescript-eslint/no-explicit-any": "off",
- "@typescript-eslint/no-non-null-assertion": "off",
- "@typescript-eslint/explicit-module-boundary-types": "off",
- "@typescript-eslint/unbound-method": "off",
-
- // ----------------------------------------------------------------------
- // Extra rules for this project specifically
- // ----------------------------------------------------------------------
-
- // Enforce React best practices
- "react-hooks/rules-of-hooks": "error",
- "react-hooks/exhaustive-deps": "error",
- "react/jsx-key": ["error", { checkFragmentShorthand: true }],
- "react/no-unescaped-entities": "error",
- "react/no-unknown-property": "error",
-
- // Relax promise rules given how we use them in this project
- "@typescript-eslint/no-floating-promises": "off",
- "@typescript-eslint/no-misused-promises": "off",
- },
-
- overrides: [
- {
- files: ["src/**/__tests__/**"],
-
- rules: {
- // Ideally, enable these lint rules again later, as they are useful to
- // catch bugs
- "@typescript-eslint/no-unsafe-argument": "off",
- "@typescript-eslint/no-unsafe-assignment": "off",
- "@typescript-eslint/no-unsafe-return": "off",
- "@typescript-eslint/unbound-method": "off",
- "@typescript-eslint/no-floating-promises": "off",
- },
- },
- {
- files: ["rollup.config.js"],
- env: {
- node: true,
- },
- },
- ],
-};
diff --git a/packages/liveblocks-react-lexical/eslint.config.mjs b/packages/liveblocks-react-lexical/eslint.config.mjs
new file mode 100644
index 00000000000..0e45a93e9d4
--- /dev/null
+++ b/packages/liveblocks-react-lexical/eslint.config.mjs
@@ -0,0 +1,73 @@
+import { makeConfig } from "@liveblocks/eslint-config";
+import commonRestrictedSyntax from "@liveblocks/eslint-config/restricted-syntax";
+import react from "eslint-plugin-react";
+import reactHooks from "eslint-plugin-react-hooks";
+
+export default [
+ ...makeConfig(),
+
+ {
+ plugins: {
+ react,
+ "react-hooks": reactHooks,
+ },
+
+ settings: {
+ react: {
+ version: "detect",
+ },
+ },
+
+ rules: {
+ // -------------------------------
+ // Custom syntax we want to forbid
+ // -------------------------------
+ "no-restricted-syntax": [
+ "error",
+ ...commonRestrictedSyntax,
+ {
+ selector:
+ "ImportDeclaration[source.value='react'] ImportSpecifier[imported.name='use']",
+ message: "use is only available on React >=19.",
+ },
+ ],
+
+ // ----------------------------------------------------------------------
+ // Overrides from default rule config used in all other projects!
+ // ----------------------------------------------------------------------
+ "@typescript-eslint/no-explicit-any": "off",
+ "@typescript-eslint/no-non-null-assertion": "off",
+ "@typescript-eslint/explicit-module-boundary-types": "off",
+ "@typescript-eslint/unbound-method": "off",
+
+ // ----------------------------------------------------------------------
+ // Extra rules for this project specifically
+ // ----------------------------------------------------------------------
+
+ // Enforce React best practices
+ "react-hooks/rules-of-hooks": "error",
+ "react-hooks/exhaustive-deps": "error",
+ "react/jsx-key": ["error", { checkFragmentShorthand: true }],
+ "react/no-unescaped-entities": "error",
+ "react/no-unknown-property": "error",
+
+ // Relax promise rules given how we use them in this project
+ "@typescript-eslint/no-floating-promises": "off",
+ "@typescript-eslint/no-misused-promises": "off",
+ },
+ },
+
+ {
+ files: ["src/**/__tests__/**"],
+
+ rules: {
+ // Ideally, enable these lint rules again later, as they are useful to
+ // catch bugs
+ "@typescript-eslint/no-unsafe-argument": "off",
+ "@typescript-eslint/no-unsafe-assignment": "off",
+ "@typescript-eslint/no-unsafe-return": "off",
+ "@typescript-eslint/unbound-method": "off",
+ "@typescript-eslint/no-floating-promises": "off",
+ },
+ },
+];
diff --git a/packages/liveblocks-react-lexical/package.json b/packages/liveblocks-react-lexical/package.json
index 2c60bb9947a..ab42b690388 100644
--- a/packages/liveblocks-react-lexical/package.json
+++ b/packages/liveblocks-react-lexical/package.json
@@ -79,7 +79,7 @@
"@liveblocks/vitest-config": "*",
"@testing-library/jest-dom": "^5.16.5",
"eslint-plugin-react": "^7.33.2",
- "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-react-hooks": "^5.2.0",
"msw": "^2.10.4",
"stylelint": "^15.10.2",
"stylelint-config-standard": "^34.0.0",
diff --git a/packages/liveblocks-react-lexical/src/comments/wrap-selection-in-thread-mark-node.ts b/packages/liveblocks-react-lexical/src/comments/wrap-selection-in-thread-mark-node.ts
index c6f81e775b8..0934fd225ee 100644
--- a/packages/liveblocks-react-lexical/src/comments/wrap-selection-in-thread-mark-node.ts
+++ b/packages/liveblocks-react-lexical/src/comments/wrap-selection-in-thread-mark-node.ts
@@ -124,7 +124,6 @@ export default function $wrapSelectionInThreadMarkNode(
}
// Make selection collapsed at the end
if ($isElementNode(lastCreatedMarkNode)) {
- // eslint-disable-next-line no-unused-expressions
isBackward
? lastCreatedMarkNode.selectStart()
: lastCreatedMarkNode.selectEnd();
diff --git a/packages/liveblocks-react-tiptap/.eslintrc.cjs b/packages/liveblocks-react-tiptap/.eslintrc.cjs
deleted file mode 100644
index 958303bf03e..00000000000
--- a/packages/liveblocks-react-tiptap/.eslintrc.cjs
+++ /dev/null
@@ -1,76 +0,0 @@
-const commonRestrictedSyntax = require("@liveblocks/eslint-config/restricted-syntax");
-
-module.exports = {
- root: true,
- extends: ["@liveblocks/eslint-config"],
- plugins: ["react", "react-hooks"],
- parserOptions: {
- ecmaFeatures: {
- jsx: true,
- },
- },
- settings: {
- react: {
- version: "detect",
- },
- },
- rules: {
- // -------------------------------
- // Custom syntax we want to forbid
- // -------------------------------
- "no-restricted-syntax": [
- "error",
- ...commonRestrictedSyntax,
- {
- selector:
- "ImportDeclaration[source.value='react'] ImportSpecifier[imported.name='use']",
- message: "use is only available on React >=19.",
- },
- ],
-
- // ----------------------------------------------------------------------
- // Overrides from default rule config used in all other projects!
- // ----------------------------------------------------------------------
- "@typescript-eslint/no-explicit-any": "off",
- "@typescript-eslint/no-non-null-assertion": "off",
- "@typescript-eslint/explicit-module-boundary-types": "off",
- "@typescript-eslint/unbound-method": "off",
-
- // ----------------------------------------------------------------------
- // Extra rules for this project specifically
- // ----------------------------------------------------------------------
-
- // Enforce React best practices
- "react-hooks/rules-of-hooks": "error",
- "react-hooks/exhaustive-deps": "error",
- "react/jsx-key": ["error", { checkFragmentShorthand: true }],
- "react/no-unescaped-entities": "error",
- "react/no-unknown-property": "error",
-
- // Relax promise rules given how we use them in this project
- "@typescript-eslint/no-floating-promises": "off",
- "@typescript-eslint/no-misused-promises": "off",
- },
-
- overrides: [
- {
- files: ["src/**/__tests__/**"],
-
- rules: {
- // Ideally, enable these lint rules again later, as they are useful to
- // catch bugs
- "@typescript-eslint/no-unsafe-argument": "off",
- "@typescript-eslint/no-unsafe-assignment": "off",
- "@typescript-eslint/no-unsafe-return": "off",
- "@typescript-eslint/unbound-method": "off",
- "@typescript-eslint/no-floating-promises": "off",
- },
- },
- {
- files: ["rollup.config.js"],
- env: {
- node: true,
- },
- },
- ],
-};
diff --git a/packages/liveblocks-react-tiptap/eslint.config.mjs b/packages/liveblocks-react-tiptap/eslint.config.mjs
new file mode 100644
index 00000000000..0e45a93e9d4
--- /dev/null
+++ b/packages/liveblocks-react-tiptap/eslint.config.mjs
@@ -0,0 +1,73 @@
+import { makeConfig } from "@liveblocks/eslint-config";
+import commonRestrictedSyntax from "@liveblocks/eslint-config/restricted-syntax";
+import react from "eslint-plugin-react";
+import reactHooks from "eslint-plugin-react-hooks";
+
+export default [
+ ...makeConfig(),
+
+ {
+ plugins: {
+ react,
+ "react-hooks": reactHooks,
+ },
+
+ settings: {
+ react: {
+ version: "detect",
+ },
+ },
+
+ rules: {
+ // -------------------------------
+ // Custom syntax we want to forbid
+ // -------------------------------
+ "no-restricted-syntax": [
+ "error",
+ ...commonRestrictedSyntax,
+ {
+ selector:
+ "ImportDeclaration[source.value='react'] ImportSpecifier[imported.name='use']",
+ message: "use is only available on React >=19.",
+ },
+ ],
+
+ // ----------------------------------------------------------------------
+ // Overrides from default rule config used in all other projects!
+ // ----------------------------------------------------------------------
+ "@typescript-eslint/no-explicit-any": "off",
+ "@typescript-eslint/no-non-null-assertion": "off",
+ "@typescript-eslint/explicit-module-boundary-types": "off",
+ "@typescript-eslint/unbound-method": "off",
+
+ // ----------------------------------------------------------------------
+ // Extra rules for this project specifically
+ // ----------------------------------------------------------------------
+
+ // Enforce React best practices
+ "react-hooks/rules-of-hooks": "error",
+ "react-hooks/exhaustive-deps": "error",
+ "react/jsx-key": ["error", { checkFragmentShorthand: true }],
+ "react/no-unescaped-entities": "error",
+ "react/no-unknown-property": "error",
+
+ // Relax promise rules given how we use them in this project
+ "@typescript-eslint/no-floating-promises": "off",
+ "@typescript-eslint/no-misused-promises": "off",
+ },
+ },
+
+ {
+ files: ["src/**/__tests__/**"],
+
+ rules: {
+ // Ideally, enable these lint rules again later, as they are useful to
+ // catch bugs
+ "@typescript-eslint/no-unsafe-argument": "off",
+ "@typescript-eslint/no-unsafe-assignment": "off",
+ "@typescript-eslint/no-unsafe-return": "off",
+ "@typescript-eslint/unbound-method": "off",
+ "@typescript-eslint/no-floating-promises": "off",
+ },
+ },
+];
diff --git a/packages/liveblocks-react-tiptap/package.json b/packages/liveblocks-react-tiptap/package.json
index fe30fabc8e1..02270290544 100644
--- a/packages/liveblocks-react-tiptap/package.json
+++ b/packages/liveblocks-react-tiptap/package.json
@@ -81,7 +81,7 @@
"@liveblocks/vitest-config": "*",
"@testing-library/jest-dom": "^5.16.5",
"eslint-plugin-react": "^7.33.2",
- "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-react-hooks": "^5.2.0",
"msw": "^2.10.4",
"stylelint": "^15.10.2",
"stylelint-config-standard": "^34.0.0",
diff --git a/packages/liveblocks-react-tiptap/src/LiveblocksExtension.ts b/packages/liveblocks-react-tiptap/src/LiveblocksExtension.ts
index 5460e5f9ecd..4c669afd17f 100644
--- a/packages/liveblocks-react-tiptap/src/LiveblocksExtension.ts
+++ b/packages/liveblocks-react-tiptap/src/LiveblocksExtension.ts
@@ -252,7 +252,6 @@ export const useLiveblocksExtension = (
const deleteTextMention = useDeleteTextMention();
// Tiptap has options default as any, in tiptap2, we could use never, but now we must use any
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
return Extension.create({
name: "liveblocksExtension",
diff --git a/packages/liveblocks-react-tiptap/src/ai/AiExtension.ts b/packages/liveblocks-react-tiptap/src/ai/AiExtension.ts
index 2754a9518f3..c35416ee8dc 100644
--- a/packages/liveblocks-react-tiptap/src/ai/AiExtension.ts
+++ b/packages/liveblocks-react-tiptap/src/ai/AiExtension.ts
@@ -47,7 +47,6 @@ function getLiveblocksYjsProvider(
editor: Editor
): LiveblocksYjsProvider | undefined {
// Eslint doesn't seem to like Tiptap's Type declaration strategy
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access
return editor.extensionStorage.liveblocksExtension?.provider;
}
diff --git a/packages/liveblocks-react-tiptap/src/ai/AiToolbar.tsx b/packages/liveblocks-react-tiptap/src/ai/AiToolbar.tsx
index 95bcf6b2491..7703e6695bf 100644
--- a/packages/liveblocks-react-tiptap/src/ai/AiToolbar.tsx
+++ b/packages/liveblocks-react-tiptap/src/ai/AiToolbar.tsx
@@ -301,7 +301,6 @@ function AiToolbarReviewingSuggestions() {
function AiToolbarCustomPromptContent() {
const editor = useCurrentEditor("CustomPromptContent", "AiToolbar");
// Eslint doesn't seem to like Tiptap's Type declaration strategy
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
const aiName = editor.storage.liveblocksAi.name;
const textAreaRef = useRef(null);
const { state, dropdownRef, isDropdownHidden } = useAiToolbarContext();
@@ -314,24 +313,18 @@ function AiToolbarCustomPromptContent() {
[customPrompt]
);
- useLayoutEffect(
- () => {
- requestAnimationFrame(() => {
- const textArea = textAreaRef.current;
+ useLayoutEffect(() => {
+ requestAnimationFrame(() => {
+ const textArea = textAreaRef.current;
- if (!textArea) {
- return;
- }
+ if (!textArea) {
+ return;
+ }
- textArea.focus();
- textArea.setSelectionRange(
- textArea.value.length,
- textArea.value.length
- );
- });
- },
- [] // eslint-disable-line react-hooks/exhaustive-deps
- );
+ textArea.focus();
+ textArea.setSelectionRange(textArea.value.length, textArea.value.length);
+ });
+ }, []);
const handlePromptKeyDown = (
event: ReactKeyboardEvent
diff --git a/packages/liveblocks-react-tiptap/src/collaboration/collaboration.ts b/packages/liveblocks-react-tiptap/src/collaboration/collaboration.ts
index 4fdc8489896..ee9727b29bb 100644
--- a/packages/liveblocks-react-tiptap/src/collaboration/collaboration.ts
+++ b/packages/liveblocks-react-tiptap/src/collaboration/collaboration.ts
@@ -229,7 +229,6 @@ export const Collaboration = Extension.create<
return {
destroy: () => {
const hasUndoManSelf = undoManager.trackedOrigins.has(undoManager);
- // eslint-disable-next-line no-underscore-dangle
const observers = undoManager._observers;
if (
@@ -245,7 +244,6 @@ export const Collaboration = Extension.create<
"afterTransaction",
undoManager.afterTransactionHandler
);
- // eslint-disable-next-line no-underscore-dangle
undoManager._observers = observers;
};
}
diff --git a/packages/liveblocks-react-tiptap/src/collaboration/helpers/isChangeOrigin.ts b/packages/liveblocks-react-tiptap/src/collaboration/helpers/isChangeOrigin.ts
index 6036966581d..0d832f92917 100644
--- a/packages/liveblocks-react-tiptap/src/collaboration/helpers/isChangeOrigin.ts
+++ b/packages/liveblocks-react-tiptap/src/collaboration/helpers/isChangeOrigin.ts
@@ -11,7 +11,7 @@
*/
// There are some lint errors in this file as it's a direct copy of the original code from Tiptap. In order to not diverge from the original code, we're disabling the lint errors.
-/* eslint-disable */
+
import type { Transaction } from "@tiptap/pm/state";
import { ySyncPluginKey } from "y-prosemirror";
diff --git a/packages/liveblocks-react-ui/.eslintrc.cjs b/packages/liveblocks-react-ui/.eslintrc.cjs
deleted file mode 100644
index 958303bf03e..00000000000
--- a/packages/liveblocks-react-ui/.eslintrc.cjs
+++ /dev/null
@@ -1,76 +0,0 @@
-const commonRestrictedSyntax = require("@liveblocks/eslint-config/restricted-syntax");
-
-module.exports = {
- root: true,
- extends: ["@liveblocks/eslint-config"],
- plugins: ["react", "react-hooks"],
- parserOptions: {
- ecmaFeatures: {
- jsx: true,
- },
- },
- settings: {
- react: {
- version: "detect",
- },
- },
- rules: {
- // -------------------------------
- // Custom syntax we want to forbid
- // -------------------------------
- "no-restricted-syntax": [
- "error",
- ...commonRestrictedSyntax,
- {
- selector:
- "ImportDeclaration[source.value='react'] ImportSpecifier[imported.name='use']",
- message: "use is only available on React >=19.",
- },
- ],
-
- // ----------------------------------------------------------------------
- // Overrides from default rule config used in all other projects!
- // ----------------------------------------------------------------------
- "@typescript-eslint/no-explicit-any": "off",
- "@typescript-eslint/no-non-null-assertion": "off",
- "@typescript-eslint/explicit-module-boundary-types": "off",
- "@typescript-eslint/unbound-method": "off",
-
- // ----------------------------------------------------------------------
- // Extra rules for this project specifically
- // ----------------------------------------------------------------------
-
- // Enforce React best practices
- "react-hooks/rules-of-hooks": "error",
- "react-hooks/exhaustive-deps": "error",
- "react/jsx-key": ["error", { checkFragmentShorthand: true }],
- "react/no-unescaped-entities": "error",
- "react/no-unknown-property": "error",
-
- // Relax promise rules given how we use them in this project
- "@typescript-eslint/no-floating-promises": "off",
- "@typescript-eslint/no-misused-promises": "off",
- },
-
- overrides: [
- {
- files: ["src/**/__tests__/**"],
-
- rules: {
- // Ideally, enable these lint rules again later, as they are useful to
- // catch bugs
- "@typescript-eslint/no-unsafe-argument": "off",
- "@typescript-eslint/no-unsafe-assignment": "off",
- "@typescript-eslint/no-unsafe-return": "off",
- "@typescript-eslint/unbound-method": "off",
- "@typescript-eslint/no-floating-promises": "off",
- },
- },
- {
- files: ["rollup.config.js"],
- env: {
- node: true,
- },
- },
- ],
-};
diff --git a/packages/liveblocks-react-ui/eslint.config.mjs b/packages/liveblocks-react-ui/eslint.config.mjs
new file mode 100644
index 00000000000..0e45a93e9d4
--- /dev/null
+++ b/packages/liveblocks-react-ui/eslint.config.mjs
@@ -0,0 +1,73 @@
+import { makeConfig } from "@liveblocks/eslint-config";
+import commonRestrictedSyntax from "@liveblocks/eslint-config/restricted-syntax";
+import react from "eslint-plugin-react";
+import reactHooks from "eslint-plugin-react-hooks";
+
+export default [
+ ...makeConfig(),
+
+ {
+ plugins: {
+ react,
+ "react-hooks": reactHooks,
+ },
+
+ settings: {
+ react: {
+ version: "detect",
+ },
+ },
+
+ rules: {
+ // -------------------------------
+ // Custom syntax we want to forbid
+ // -------------------------------
+ "no-restricted-syntax": [
+ "error",
+ ...commonRestrictedSyntax,
+ {
+ selector:
+ "ImportDeclaration[source.value='react'] ImportSpecifier[imported.name='use']",
+ message: "use is only available on React >=19.",
+ },
+ ],
+
+ // ----------------------------------------------------------------------
+ // Overrides from default rule config used in all other projects!
+ // ----------------------------------------------------------------------
+ "@typescript-eslint/no-explicit-any": "off",
+ "@typescript-eslint/no-non-null-assertion": "off",
+ "@typescript-eslint/explicit-module-boundary-types": "off",
+ "@typescript-eslint/unbound-method": "off",
+
+ // ----------------------------------------------------------------------
+ // Extra rules for this project specifically
+ // ----------------------------------------------------------------------
+
+ // Enforce React best practices
+ "react-hooks/rules-of-hooks": "error",
+ "react-hooks/exhaustive-deps": "error",
+ "react/jsx-key": ["error", { checkFragmentShorthand: true }],
+ "react/no-unescaped-entities": "error",
+ "react/no-unknown-property": "error",
+
+ // Relax promise rules given how we use them in this project
+ "@typescript-eslint/no-floating-promises": "off",
+ "@typescript-eslint/no-misused-promises": "off",
+ },
+ },
+
+ {
+ files: ["src/**/__tests__/**"],
+
+ rules: {
+ // Ideally, enable these lint rules again later, as they are useful to
+ // catch bugs
+ "@typescript-eslint/no-unsafe-argument": "off",
+ "@typescript-eslint/no-unsafe-assignment": "off",
+ "@typescript-eslint/no-unsafe-return": "off",
+ "@typescript-eslint/unbound-method": "off",
+ "@typescript-eslint/no-floating-promises": "off",
+ },
+ },
+];
diff --git a/packages/liveblocks-react-ui/package.json b/packages/liveblocks-react-ui/package.json
index b1e4d1eb721..4559dd65c93 100644
--- a/packages/liveblocks-react-ui/package.json
+++ b/packages/liveblocks-react-ui/package.json
@@ -110,7 +110,7 @@
"@testing-library/jest-dom": "^6.8.0",
"@testing-library/react": "^16.3.0",
"eslint-plugin-react": "^7.33.2",
- "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-react-hooks": "^5.2.0",
"msw": "^2.10.4",
"stylelint": "^15.10.2",
"stylelint-config-standard": "^34.0.0",
diff --git a/packages/liveblocks-react-ui/src/primitives/Duration.tsx b/packages/liveblocks-react-ui/src/primitives/Duration.tsx
index 4ce5fd4d7d1..751eff6259b 100644
--- a/packages/liveblocks-react-ui/src/primitives/Duration.tsx
+++ b/packages/liveblocks-react-ui/src/primitives/Duration.tsx
@@ -328,7 +328,6 @@ export const Duration = forwardRef(
typeof renderTitle === "function"
? renderTitle(resolvedDuration, locale)
: renderTitle,
- // eslint-disable-next-line react-hooks/exhaustive-deps
[renderTitle, resolvedDuration, locale]
);
const children = useMemo(
diff --git a/packages/liveblocks-react/.eslintrc.cjs b/packages/liveblocks-react/.eslintrc.cjs
deleted file mode 100644
index 65fd65bfa9d..00000000000
--- a/packages/liveblocks-react/.eslintrc.cjs
+++ /dev/null
@@ -1,60 +0,0 @@
-const commonRestrictedSyntax = require("@liveblocks/eslint-config/restricted-syntax");
-
-module.exports = {
- root: true,
- extends: ["@liveblocks/eslint-config"],
- plugins: ["react-hooks"],
- rules: {
- // -------------------------------
- // Custom syntax we want to forbid
- // -------------------------------
- "no-restricted-syntax": [
- "error",
- ...commonRestrictedSyntax,
- {
- selector:
- "ImportDeclaration[source.value='react'] ImportSpecifier[imported.name='use']",
- message: "use is only available on React >=19.",
- },
- {
- selector:
- "ImportDeclaration[source.value='react'] ImportSpecifier[imported.name='useLayoutEffect']",
- message:
- "useLayoutEffect triggers a warning when executed on the server on React <=18.2.0. Import it from './lib/use-layout-effect' instead.",
- },
- ],
-
- // ----------------------------------------------------------------------
- // Overrides from default rule config used in all other projects!
- // ----------------------------------------------------------------------
- "@typescript-eslint/no-explicit-any": "off",
- "@typescript-eslint/no-non-null-assertion": "off",
- "@typescript-eslint/explicit-module-boundary-types": "off",
- "@typescript-eslint/unbound-method": "off",
-
- // ----------------------------------------------------------------------
- // Extra rules for this project specifically
- // ----------------------------------------------------------------------
-
- // Enforce React best practices
- "react-hooks/rules-of-hooks": "error",
- "react-hooks/exhaustive-deps": "error",
- },
-
- overrides: [
- {
- files: ["src/**/__tests__/**"],
-
- rules: {
- // Ideally, enable these lint rules again later, as they are useful to
- // catch bugs
- "@typescript-eslint/no-unsafe-argument": "off",
- "@typescript-eslint/no-unsafe-assignment": "off",
- "@typescript-eslint/no-unsafe-return": "off",
- "@typescript-eslint/unbound-method": "off",
- "@typescript-eslint/no-floating-promises": "off",
- "@typescript-eslint/require-await": "off", // Fine in test mocks
- },
- },
- ],
-};
diff --git a/packages/liveblocks-react/eslint.config.mjs b/packages/liveblocks-react/eslint.config.mjs
new file mode 100644
index 00000000000..76339332adc
--- /dev/null
+++ b/packages/liveblocks-react/eslint.config.mjs
@@ -0,0 +1,71 @@
+import { makeConfig } from "@liveblocks/eslint-config";
+import commonRestrictedSyntax from "@liveblocks/eslint-config/restricted-syntax";
+import reactHooks from "eslint-plugin-react-hooks";
+
+export default [
+ ...makeConfig(),
+
+ {
+ plugins: {
+ "react-hooks": reactHooks,
+ },
+
+ rules: {
+ // -------------------------------
+ // Custom syntax we want to forbid
+ // -------------------------------
+ "no-restricted-syntax": [
+ "error",
+ ...commonRestrictedSyntax,
+ {
+ selector:
+ "ImportDeclaration[source.value='react'] ImportSpecifier[imported.name='use']",
+ message: "use is only available on React >=19.",
+ },
+ {
+ selector:
+ "ImportDeclaration[source.value='react'] ImportSpecifier[imported.name='useLayoutEffect']",
+ message:
+ "useLayoutEffect triggers a warning when executed on the server on React <=18.2.0. Import it from './lib/use-layout-effect' instead.",
+ },
+ ],
+
+ // ----------------------------------------------------------------------
+ // Overrides from default rule config used in all other projects!
+ // ----------------------------------------------------------------------
+ "@typescript-eslint/no-explicit-any": "off",
+ "@typescript-eslint/no-non-null-assertion": "off",
+ "@typescript-eslint/explicit-module-boundary-types": "off",
+ "@typescript-eslint/unbound-method": "off",
+
+ // TODO: New rules in typescript-eslint v8's recommendedTypeChecked
+ // that weren't in v7. Disabled during the v8 migration to keep it
+ // clean, but we should revisit and enable these later.
+ "@typescript-eslint/only-throw-error": "off",
+ "@typescript-eslint/prefer-promise-reject-errors": "off",
+
+ // ----------------------------------------------------------------------
+ // Extra rules for this project specifically
+ // ----------------------------------------------------------------------
+
+ // Enforce React best practices
+ "react-hooks/rules-of-hooks": "error",
+ "react-hooks/exhaustive-deps": "error",
+ },
+ },
+
+ {
+ files: ["src/**/__tests__/**"],
+
+ rules: {
+ // Ideally, enable these lint rules again later, as they are useful to
+ // catch bugs
+ "@typescript-eslint/no-unsafe-argument": "off",
+ "@typescript-eslint/no-unsafe-assignment": "off",
+ "@typescript-eslint/no-unsafe-return": "off",
+ "@typescript-eslint/unbound-method": "off",
+ "@typescript-eslint/no-floating-promises": "off",
+ "@typescript-eslint/require-await": "off", // Fine in test mocks
+ },
+ },
+];
diff --git a/packages/liveblocks-react/package.json b/packages/liveblocks-react/package.json
index dabdeddfc3c..ac44d6d3d58 100644
--- a/packages/liveblocks-react/package.json
+++ b/packages/liveblocks-react/package.json
@@ -86,7 +86,7 @@
"@testing-library/jest-dom": "^6.8.0",
"@testing-library/react": "^16.3.0",
"date-fns": "^3.6.0",
- "eslint-plugin-react-hooks": "^4.6.2",
+ "eslint-plugin-react-hooks": "^5.2.0",
"itertools": "^2.3.2",
"msw": "^2.10.4",
"react-error-boundary": "^4.0.13"
diff --git a/packages/liveblocks-react/src/lib/use-initial.ts b/packages/liveblocks-react/src/lib/use-initial.ts
index fcb4214e2b8..6f977a132e5 100644
--- a/packages/liveblocks-react/src/lib/use-initial.ts
+++ b/packages/liveblocks-react/src/lib/use-initial.ts
@@ -27,7 +27,6 @@ export function useInitialUnlessFunction(
type Fn = T & ((...args: unknown[]) => unknown);
const ref = useLatest(latestValue as Fn);
- // eslint-disable-next-line react-hooks/exhaustive-deps
const wrapper = useCallback(
((...args: unknown[]) => ref.current(...args)) as Fn,
[ref]
diff --git a/packages/liveblocks-react/src/room.tsx b/packages/liveblocks-react/src/room.tsx
index fa38054c009..76fcb670d48 100644
--- a/packages/liveblocks-react/src/room.tsx
+++ b/packages/liveblocks-react/src/room.tsx
@@ -4706,6 +4706,7 @@ function _useOthers(
isEqual?: (prev: T, curr: T) => boolean
): T;
function _useOthers(...args: any[]) {
+ // eslint-disable-next-line react-hooks/rules-of-hooks -- internal wrapper
return useOthers(...(args as []));
}
@@ -4766,6 +4767,7 @@ function _useOthersSuspense(
isEqual?: (prev: T, curr: T) => boolean
): T;
function _useOthersSuspense(...args: any[]) {
+ // eslint-disable-next-line react-hooks/rules-of-hooks -- internal wrapper
return useOthersSuspense(...(args as []));
}
@@ -4850,6 +4852,7 @@ function _useSelf(
isEqual?: (prev: T, curr: T) => boolean
): T | null;
function _useSelf(...args: any[]) {
+ // eslint-disable-next-line react-hooks/rules-of-hooks -- internal wrapper
return useSelf(...(args as []));
}
@@ -4885,6 +4888,7 @@ function _useSelfSuspense(
isEqual?: (prev: T, curr: T) => boolean
): T;
function _useSelfSuspense(...args: any[]) {
+ // eslint-disable-next-line react-hooks/rules-of-hooks -- internal wrapper
return useSelfSuspense(...(args as []));
}
diff --git a/packages/liveblocks-react/src/use-sync-external-store-with-selector.ts b/packages/liveblocks-react/src/use-sync-external-store-with-selector.ts
index bd4f5e9ad0b..9404aa0f349 100644
--- a/packages/liveblocks-react/src/use-sync-external-store-with-selector.ts
+++ b/packages/liveblocks-react/src/use-sync-external-store-with-selector.ts
@@ -19,9 +19,7 @@ import {
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
*/
function is(x: any, y: any) {
- return (
- (x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y) // eslint-disable-line no-self-compare
- );
+ return (x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y);
}
// Same as useSyncExternalStore, but supports selector and isEqual arguments.
diff --git a/packages/liveblocks-redux/.eslintrc.cjs b/packages/liveblocks-redux/.eslintrc.cjs
deleted file mode 100644
index 44e6b3ca466..00000000000
--- a/packages/liveblocks-redux/.eslintrc.cjs
+++ /dev/null
@@ -1,32 +0,0 @@
-const commonRestrictedSyntax = require("@liveblocks/eslint-config/restricted-syntax");
-
-module.exports = {
- root: true,
- extends: ["@liveblocks/eslint-config"],
- rules: {
- // -------------------------------
- // Custom syntax we want to forbid
- // -------------------------------
- "no-restricted-syntax": ["error", ...commonRestrictedSyntax],
-
- // ----------------------------------------------------------------------
- // Overrides from default rule config used in all other projects!
- // ----------------------------------------------------------------------
- "@typescript-eslint/no-explicit-any": "off",
- "@typescript-eslint/no-non-null-assertion": "off",
- eqeqeq: "off",
-
- // Ideally, enable these lint rules again later, as they are useful
- // to catch bugs
- "@typescript-eslint/no-unsafe-argument": "off",
- "@typescript-eslint/no-unsafe-assignment": "off",
- "@typescript-eslint/no-unsafe-call": "off",
- "@typescript-eslint/no-unsafe-member-access": "off",
- "@typescript-eslint/no-unsafe-return": "off",
-
- // ----------------------------------------------------------------------
- // Extra rules for this project specifically
- // ----------------------------------------------------------------------
- /* None yet 😇 ! */
- },
-};
diff --git a/packages/liveblocks-redux/eslint.config.mjs b/packages/liveblocks-redux/eslint.config.mjs
new file mode 100644
index 00000000000..c2250d496b7
--- /dev/null
+++ b/packages/liveblocks-redux/eslint.config.mjs
@@ -0,0 +1,35 @@
+import { makeConfig } from "@liveblocks/eslint-config";
+import commonRestrictedSyntax from "@liveblocks/eslint-config/restricted-syntax";
+
+export default [
+ ...makeConfig(),
+
+ {
+ rules: {
+ // -------------------------------
+ // Custom syntax we want to forbid
+ // -------------------------------
+ "no-restricted-syntax": ["error", ...commonRestrictedSyntax],
+
+ // ----------------------------------------------------------------------
+ // Overrides from default rule config used in all other projects!
+ // ----------------------------------------------------------------------
+ "@typescript-eslint/no-explicit-any": "off",
+ "@typescript-eslint/no-non-null-assertion": "off",
+ eqeqeq: "off",
+
+ // Ideally, enable these lint rules again later, as they are useful
+ // to catch bugs
+ "@typescript-eslint/no-unsafe-argument": "off",
+ "@typescript-eslint/no-unsafe-assignment": "off",
+ "@typescript-eslint/no-unsafe-call": "off",
+ "@typescript-eslint/no-unsafe-member-access": "off",
+ "@typescript-eslint/no-unsafe-return": "off",
+
+ // ----------------------------------------------------------------------
+ // Extra rules for this project specifically
+ // ----------------------------------------------------------------------
+ /* None yet 😇 ! */
+ },
+ },
+];
diff --git a/packages/liveblocks-yjs/.eslintrc.cjs b/packages/liveblocks-yjs/.eslintrc.cjs
deleted file mode 100644
index 2cbceeec907..00000000000
--- a/packages/liveblocks-yjs/.eslintrc.cjs
+++ /dev/null
@@ -1,43 +0,0 @@
-const commonRestrictedSyntax = require("@liveblocks/eslint-config/restricted-syntax");
-
-module.exports = {
- root: true,
- extends: ["@liveblocks/eslint-config"],
- rules: {
- // -------------------------------
- // Custom syntax we want to forbid
- // -------------------------------
- "no-restricted-syntax": ["error", ...commonRestrictedSyntax],
-
- // ----------------------------------------------------------------------
- // Overrides from default rule config used in all other projects!
- // ----------------------------------------------------------------------
- "@typescript-eslint/no-explicit-any": "off",
- "@typescript-eslint/no-non-null-assertion": "off",
- eqeqeq: "off",
-
- // ----------------------------------------------------------------------
- // Extra rules for this project specifically
- // ----------------------------------------------------------------------
- /* None yet 😇 ! */
- },
-
- overrides: [
- {
- files: ["src/__tests__/**"],
-
- // Special config for test files
- rules: {
- "@typescript-eslint/explicit-module-boundary-types": "off",
-
- // Ideally, enable these lint rules again later, as they are useful
- // to catch bugs
- "@typescript-eslint/no-unsafe-argument": "off",
- "@typescript-eslint/no-unsafe-assignment": "off",
- // "@typescript-eslint/no-unsafe-call": "off",
- // "@typescript-eslint/no-unsafe-member-access": "off",
- // "@typescript-eslint/no-unsafe-return": "off",
- },
- },
- ],
-};
diff --git a/packages/liveblocks-yjs/eslint.config.mjs b/packages/liveblocks-yjs/eslint.config.mjs
new file mode 100644
index 00000000000..aa3b7795a6f
--- /dev/null
+++ b/packages/liveblocks-yjs/eslint.config.mjs
@@ -0,0 +1,44 @@
+import { makeConfig } from "@liveblocks/eslint-config";
+import commonRestrictedSyntax from "@liveblocks/eslint-config/restricted-syntax";
+
+export default [
+ ...makeConfig(),
+
+ {
+ rules: {
+ // -------------------------------
+ // Custom syntax we want to forbid
+ // -------------------------------
+ "no-restricted-syntax": ["error", ...commonRestrictedSyntax],
+
+ // ----------------------------------------------------------------------
+ // Overrides from default rule config used in all other projects!
+ // ----------------------------------------------------------------------
+ "@typescript-eslint/no-explicit-any": "off",
+ "@typescript-eslint/no-non-null-assertion": "off",
+ eqeqeq: "off",
+
+ // ----------------------------------------------------------------------
+ // Extra rules for this project specifically
+ // ----------------------------------------------------------------------
+ /* None yet 😇 ! */
+ },
+ },
+
+ {
+ files: ["src/__tests__/**"],
+
+ // Special config for test files
+ rules: {
+ "@typescript-eslint/explicit-module-boundary-types": "off",
+
+ // Ideally, enable these lint rules again later, as they are useful
+ // to catch bugs
+ "@typescript-eslint/no-unsafe-argument": "off",
+ "@typescript-eslint/no-unsafe-assignment": "off",
+ // "@typescript-eslint/no-unsafe-call": "off",
+ // "@typescript-eslint/no-unsafe-member-access": "off",
+ // "@typescript-eslint/no-unsafe-return": "off",
+ },
+ },
+];
diff --git a/packages/liveblocks-yjs/src/__tests__/index.test.ts b/packages/liveblocks-yjs/src/__tests__/index.test.ts
index 7657f8abf8e..40807ce6302 100644
--- a/packages/liveblocks-yjs/src/__tests__/index.test.ts
+++ b/packages/liveblocks-yjs/src/__tests__/index.test.ts
@@ -1,6 +1,5 @@
import { describe, expect, test } from "vitest";
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { LiveblocksYjsProvider } from "..";
describe("@liveblocks/yjs", () => {
diff --git a/packages/liveblocks-yjs/src/awareness.ts b/packages/liveblocks-yjs/src/awareness.ts
index 573a38a0fcb..2790bf7faa9 100644
--- a/packages/liveblocks-yjs/src/awareness.ts
+++ b/packages/liveblocks-yjs/src/awareness.ts
@@ -1,7 +1,3 @@
-// TODO: apparently Yjs is full of anys or something, see if we can fix this
-/* eslint-disable @typescript-eslint/no-unsafe-call */
-/* eslint-disable @typescript-eslint/no-unsafe-member-access */
-/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import type { BaseUserMeta, JsonObject, User } from "@liveblocks/client";
import type { OpaqueRoom } from "@liveblocks/core";
import { Observable } from "lib0/observable";
diff --git a/packages/liveblocks-zustand/.eslintrc.cjs b/packages/liveblocks-zustand/.eslintrc.cjs
deleted file mode 100644
index aef6cc2bf02..00000000000
--- a/packages/liveblocks-zustand/.eslintrc.cjs
+++ /dev/null
@@ -1,41 +0,0 @@
-const commonRestrictedSyntax = require("@liveblocks/eslint-config/restricted-syntax");
-
-module.exports = {
- root: true,
- extends: ["@liveblocks/eslint-config"],
- rules: {
- // -------------------------------
- // Custom syntax we want to forbid
- // -------------------------------
- "no-restricted-syntax": ["error", ...commonRestrictedSyntax],
-
- // ----------------------------------------------------------------------
- // Overrides from default rule config used in all other projects!
- // ----------------------------------------------------------------------
- "@typescript-eslint/no-explicit-any": "off",
- "@typescript-eslint/no-non-null-assertion": "off",
- eqeqeq: "off",
-
- // ----------------------------------------------------------------------
- // Extra rules for this project specifically
- // ----------------------------------------------------------------------
- /* None yet 😇 ! */
- },
-
- overrides: [
- {
- files: ["src/__tests__/**"],
-
- // Special config for test files
- rules: {
- // Ideally, enable these lint rules again later, as they are useful
- // to catch bugs
- "@typescript-eslint/no-unsafe-argument": "off",
- "@typescript-eslint/no-unsafe-assignment": "off",
- // "@typescript-eslint/no-unsafe-call": "off",
- // "@typescript-eslint/no-unsafe-member-access": "off",
- // "@typescript-eslint/no-unsafe-return": "off",
- },
- },
- ],
-};
diff --git a/packages/liveblocks-zustand/eslint.config.mjs b/packages/liveblocks-zustand/eslint.config.mjs
new file mode 100644
index 00000000000..6cb7e7bd1ff
--- /dev/null
+++ b/packages/liveblocks-zustand/eslint.config.mjs
@@ -0,0 +1,42 @@
+import { makeConfig } from "@liveblocks/eslint-config";
+import commonRestrictedSyntax from "@liveblocks/eslint-config/restricted-syntax";
+
+export default [
+ ...makeConfig(),
+
+ {
+ rules: {
+ // -------------------------------
+ // Custom syntax we want to forbid
+ // -------------------------------
+ "no-restricted-syntax": ["error", ...commonRestrictedSyntax],
+
+ // ----------------------------------------------------------------------
+ // Overrides from default rule config used in all other projects!
+ // ----------------------------------------------------------------------
+ "@typescript-eslint/no-explicit-any": "off",
+ "@typescript-eslint/no-non-null-assertion": "off",
+ eqeqeq: "off",
+
+ // ----------------------------------------------------------------------
+ // Extra rules for this project specifically
+ // ----------------------------------------------------------------------
+ /* None yet 😇 ! */
+ },
+ },
+
+ {
+ files: ["src/__tests__/**"],
+
+ // Special config for test files
+ rules: {
+ // Ideally, enable these lint rules again later, as they are useful
+ // to catch bugs
+ "@typescript-eslint/no-unsafe-argument": "off",
+ "@typescript-eslint/no-unsafe-assignment": "off",
+ // "@typescript-eslint/no-unsafe-call": "off",
+ // "@typescript-eslint/no-unsafe-member-access": "off",
+ // "@typescript-eslint/no-unsafe-return": "off",
+ },
+ },
+];
diff --git a/shared/eslint-config/index.js b/shared/eslint-config/index.js
index 16fc6d9745f..ed11d67fb8a 100644
--- a/shared/eslint-config/index.js
+++ b/shared/eslint-config/index.js
@@ -1,65 +1,86 @@
-module.exports = {
- parser: "@typescript-eslint/parser",
- parserOptions: {
- // Each project's individual/local tsconfig.json defines the behavior
- // of the parser
- project: ["./tsconfig.json"],
- },
+import js from "@eslint/js";
+import importPlugin from "eslint-plugin-import";
+import simpleImportSort from "eslint-plugin-simple-import-sort";
+import tseslint from "typescript-eslint";
- plugins: [
- "@typescript-eslint",
- "eslint-plugin-import",
- "eslint-plugin-simple-import-sort",
- ],
+/**
+ * Creates the base ESLint flat config used by all packages in the monorepo.
+ *
+ * @param {string} tsconfigPath Path to the tsconfig.json (default: "./tsconfig.json")
+ * @returns {import("eslint").Linter.Config[]}
+ */
+export function makeConfig(tsconfigPath = "./tsconfig.json") {
+ return [
+ js.configs.recommended,
+ ...tseslint.configs.recommendedTypeChecked,
- extends: [
- "eslint:recommended",
- "plugin:@typescript-eslint/recommended",
- "plugin:@typescript-eslint/recommended-requiring-type-checking",
- ],
+ {
+ languageOptions: {
+ parserOptions: {
+ // Each project's individual/local tsconfig.json defines the behavior
+ // of the parser
+ projectService: {
+ defaultProject: tsconfigPath,
+ },
+ },
+ },
- // Rules that are enabled for _all_ packages by default
- rules: {
- "@typescript-eslint/no-explicit-any": "error",
+ plugins: {
+ import: importPlugin,
+ "simple-import-sort": simpleImportSort,
+ },
- // -------------------------------
- // Not interested in these checks:
- // -------------------------------
- "@typescript-eslint/no-empty-function": "off",
- "@typescript-eslint/no-inferrable-types": "off",
- "no-constant-condition": "off",
- "@typescript-eslint/no-non-null-assertion": "off", // Because we have a custom no-restricted-syntax rule for this
- "@typescript-eslint/no-base-to-string": "off", // Too many false positives for Yjs objects
+ // Rules that are enabled for _all_ packages by default
+ rules: {
+ "@typescript-eslint/no-explicit-any": "error",
- // -----------------------------
- // Enable auto-fixes for imports
- // -----------------------------
- "import/no-duplicates": "error",
- "@typescript-eslint/consistent-type-imports": "error",
- "simple-import-sort/imports": "error",
- "simple-import-sort/exports": "error",
+ // -------------------------------
+ // Not interested in these checks:
+ // -------------------------------
+ "@typescript-eslint/no-empty-function": "off",
+ "@typescript-eslint/no-inferrable-types": "off",
+ "no-constant-condition": "off",
+ "@typescript-eslint/no-non-null-assertion": "off", // Because we have a custom no-restricted-syntax rule for this
+ "@typescript-eslint/no-base-to-string": "off", // Too many false positives for Yjs objects
- // ------------------------
- // Customized default rules
- // ------------------------
- eqeqeq: ["error", "always"],
- quotes: [
- "error",
- "double",
- { avoidEscape: true, allowTemplateLiterals: false },
- ],
- "object-shorthand": "error",
- "@typescript-eslint/explicit-module-boundary-types": "error",
- "@typescript-eslint/no-unused-vars": [
- "warn",
- // Unused variables are fine if they start with an underscore
- { args: "all", argsIgnorePattern: "^_.*", varsIgnorePattern: "^_.*" },
- ],
+ // -----------------------------
+ // Enable auto-fixes for imports
+ // -----------------------------
+ "import/no-duplicates": "error",
+ "@typescript-eslint/consistent-type-imports": "error",
+ "simple-import-sort/imports": "error",
+ "simple-import-sort/exports": "error",
- // --------------------------------------------------------------
- // "The Code is the To-Do List"
- // https://www.executeprogram.com/blog/the-code-is-the-to-do-list
- // --------------------------------------------------------------
- "no-warning-comments": ["error", { terms: ["xxx"], location: "anywhere" }],
- },
-};
+ // ------------------------
+ // Customized default rules
+ // ------------------------
+ eqeqeq: ["error", "always"],
+ quotes: [
+ "error",
+ "double",
+ { avoidEscape: true, allowTemplateLiterals: false },
+ ],
+ "object-shorthand": "error",
+ "@typescript-eslint/explicit-module-boundary-types": "error",
+ "@typescript-eslint/no-unused-vars": [
+ "warn",
+ // Unused variables are fine if they start with an underscore
+ {
+ args: "all",
+ argsIgnorePattern: "^_.*",
+ varsIgnorePattern: "^_.*",
+ },
+ ],
+
+ // --------------------------------------------------------------
+ // "The Code is the To-Do List"
+ // https://www.executeprogram.com/blog/the-code-is-the-to-do-list
+ // --------------------------------------------------------------
+ "no-warning-comments": [
+ "error",
+ { terms: ["xxx"], location: "anywhere" },
+ ],
+ },
+ },
+ ];
+}
diff --git a/shared/eslint-config/package.json b/shared/eslint-config/package.json
index 6d43799deea..c1c894669af 100644
--- a/shared/eslint-config/package.json
+++ b/shared/eslint-config/package.json
@@ -1,12 +1,16 @@
{
"name": "@liveblocks/eslint-config",
"private": true,
- "main": "index.js",
+ "type": "module",
+ "exports": {
+ ".": "./index.js",
+ "./restricted-syntax": "./restricted-syntax.js"
+ },
"dependencies": {
- "@typescript-eslint/eslint-plugin": "^7.13.1",
- "@typescript-eslint/parser": "^7.13.1",
- "eslint": "^8.56.0",
- "eslint-plugin-import": "^2.29.1",
- "eslint-plugin-simple-import-sort": "^12.1.0"
+ "@eslint/js": "^9.39.4",
+ "eslint": "^9.39.4",
+ "eslint-plugin-import": "^2.32.0",
+ "eslint-plugin-simple-import-sort": "^13.0.0",
+ "typescript-eslint": "^8.58.2"
}
}
diff --git a/shared/eslint-config/restricted-syntax.js b/shared/eslint-config/restricted-syntax.js
index d9ea7a2580f..869a1f08c91 100644
--- a/shared/eslint-config/restricted-syntax.js
+++ b/shared/eslint-config/restricted-syntax.js
@@ -1,4 +1,4 @@
-module.exports = [
+export default [
{
selector: 'TSTypeReference[typeName.name="AbstractCrdt"]',
message: "Don't refer to AbstractCrdt as a type. Use LiveNode instead.",
@@ -18,7 +18,6 @@ module.exports = [
{
selector:
"ImportDeclaration[source.value='vitest'] ImportSpecifier[imported.name='it']",
- message:
- "Import 'test' instead of 'it' from vitest.",
+ message: "Import 'test' instead of 'it' from vitest.",
},
];
diff --git a/tools/liveblocks-codemod/.eslintignore b/tools/liveblocks-codemod/.eslintignore
deleted file mode 100644
index a0b51a6b990..00000000000
--- a/tools/liveblocks-codemod/.eslintignore
+++ /dev/null
@@ -1,2 +0,0 @@
-__tests__
-__testfixtures__
diff --git a/tools/liveblocks-codemod/.eslintrc.cjs b/tools/liveblocks-codemod/.eslintrc.cjs
deleted file mode 100644
index 4e836f04e80..00000000000
--- a/tools/liveblocks-codemod/.eslintrc.cjs
+++ /dev/null
@@ -1,14 +0,0 @@
-module.exports = {
- root: true,
- extends: ["@liveblocks/eslint-config"],
- rules: {
- // ----------------------------------------------------------------------
- // Overrides from default rule config used in all other projects!
- // ----------------------------------------------------------------------
- /* None yet 😇 ! */
- // ----------------------------------------------------------------------
- // Extra rules for this project specifically
- // ----------------------------------------------------------------------
- "@typescript-eslint/explicit-module-boundary-types": "off",
- },
-};
diff --git a/tools/liveblocks-codemod/eslint.config.mjs b/tools/liveblocks-codemod/eslint.config.mjs
new file mode 100644
index 00000000000..dd88ca8d33c
--- /dev/null
+++ b/tools/liveblocks-codemod/eslint.config.mjs
@@ -0,0 +1,18 @@
+import { makeConfig } from "@liveblocks/eslint-config";
+
+export default [
+ ...makeConfig(),
+
+ {
+ ignores: ["**/__tests__/**", "**/__testfixtures__/**"],
+ },
+
+ {
+ rules: {
+ // ----------------------------------------------------------------------
+ // Overrides from default rule config used in all other projects!
+ // ----------------------------------------------------------------------
+ "@typescript-eslint/explicit-module-boundary-types": "off",
+ },
+ },
+];
diff --git a/tools/liveblocks-codemod/src/lib/find-and-replace.ts b/tools/liveblocks-codemod/src/lib/find-and-replace.ts
index 0d4b4f3cd7b..e8ec55966ed 100644
--- a/tools/liveblocks-codemod/src/lib/find-and-replace.ts
+++ b/tools/liveblocks-codemod/src/lib/find-and-replace.ts
@@ -17,7 +17,7 @@ export function findAndReplace(
fs.writeFileSync(file, callback(content), { encoding: "utf-8" });
}
- } catch (error) {
+ } catch {
// console.error(error);
}
}
diff --git a/tools/liveblocks-devtools/.eslintrc.cjs b/tools/liveblocks-devtools/.eslintrc.cjs
deleted file mode 100644
index 52206b89326..00000000000
--- a/tools/liveblocks-devtools/.eslintrc.cjs
+++ /dev/null
@@ -1,27 +0,0 @@
-// const commonRestrictedSyntax = require("@liveblocks/eslint-config/restricted-syntax");
-
-module.exports = {
- root: true,
- extends: ["@liveblocks/eslint-config"],
- plugins: ["react-hooks"],
- rules: {
- // -------------------------------
- // Custom syntax we want to forbid
- // -------------------------------
- // "no-restricted-syntax": ["error", ...commonRestrictedSyntax],
-
- // ----------------------------------------------------------------------
- // Overrides from default rule config used in all other projects!
- // ----------------------------------------------------------------------
- "@typescript-eslint/explicit-module-boundary-types": "off",
- "@typescript-eslint/unbound-method": "off",
-
- // ----------------------------------------------------------------------
- // Extra rules for this project specifically
- // ----------------------------------------------------------------------
-
- // Enforce React best practices
- "react-hooks/rules-of-hooks": "error",
- "react-hooks/exhaustive-deps": "error",
- },
-};
diff --git a/tools/liveblocks-devtools/eslint.config.mjs b/tools/liveblocks-devtools/eslint.config.mjs
new file mode 100644
index 00000000000..5552c525612
--- /dev/null
+++ b/tools/liveblocks-devtools/eslint.config.mjs
@@ -0,0 +1,36 @@
+import { makeConfig } from "@liveblocks/eslint-config";
+import reactHooks from "eslint-plugin-react-hooks";
+
+export default [
+ ...makeConfig(),
+
+ {
+ plugins: {
+ "react-hooks": reactHooks,
+ },
+
+ rules: {
+ // ----------------------------------------------------------------------
+ // Overrides from default rule config used in all other projects!
+ // ----------------------------------------------------------------------
+ "@typescript-eslint/explicit-module-boundary-types": "off",
+ "@typescript-eslint/unbound-method": "off",
+ "@typescript-eslint/no-explicit-any": "off",
+
+ // TODO: New rules in typescript-eslint v8's recommendedTypeChecked
+ // that weren't in v7. Disabled during the v8 migration to keep it
+ // clean, but we should revisit and enable these later.
+ "@typescript-eslint/no-unsafe-assignment": "off",
+ "@typescript-eslint/no-unsafe-argument": "off",
+ "@typescript-eslint/restrict-template-expressions": "off",
+
+ // ----------------------------------------------------------------------
+ // Extra rules for this project specifically
+ // ----------------------------------------------------------------------
+
+ // Enforce React best practices
+ "react-hooks/rules-of-hooks": "error",
+ "react-hooks/exhaustive-deps": "error",
+ },
+ },
+];
diff --git a/tools/liveblocks-devtools/package.json b/tools/liveblocks-devtools/package.json
index 870e3b96734..fe5f04dc30d 100644
--- a/tools/liveblocks-devtools/package.json
+++ b/tools/liveblocks-devtools/package.json
@@ -37,9 +37,10 @@
"yjs": "^13.6.14"
},
"devDependencies": {
+ "@liveblocks/eslint-config": "*",
"@types/webextension-polyfill": "^0.10.0",
"autoprefixer": "^10.4.13",
- "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-react-hooks": "^5.2.0",
"postcss": "^8.4.20",
"prettier-plugin-tailwindcss": "^0.5.4",
"tailwindcss": "^3.2.4",
diff --git a/tools/liveblocks-devtools/src/devtools/components/Dialog.tsx b/tools/liveblocks-devtools/src/devtools/components/Dialog.tsx
index 552f53c886c..5889dd77288 100644
--- a/tools/liveblocks-devtools/src/devtools/components/Dialog.tsx
+++ b/tools/liveblocks-devtools/src/devtools/components/Dialog.tsx
@@ -4,7 +4,8 @@ import type { ReactNode } from "react";
import { forwardRef } from "react";
export interface Props
- extends RadixDialog.DialogProps,
+ extends
+ RadixDialog.DialogProps,
Omit {
content: ReactNode;
}
diff --git a/tools/liveblocks-devtools/src/devtools/components/ResizablePanel.tsx b/tools/liveblocks-devtools/src/devtools/components/ResizablePanel.tsx
index 69cf448e9ab..cf8eda53e9f 100644
--- a/tools/liveblocks-devtools/src/devtools/components/ResizablePanel.tsx
+++ b/tools/liveblocks-devtools/src/devtools/components/ResizablePanel.tsx
@@ -169,7 +169,6 @@ export function ResizablePanel({
, "content"> {
+export interface SelectItem extends Omit<
+ ComponentProps,
+ "content"
+> {
value: string;
content?: ReactNode;
}
diff --git a/tools/liveblocks-devtools/src/devtools/components/Tabs.tsx b/tools/liveblocks-devtools/src/devtools/components/Tabs.tsx
index 2c8f8da3bd3..d466ad33485 100644
--- a/tools/liveblocks-devtools/src/devtools/components/Tabs.tsx
+++ b/tools/liveblocks-devtools/src/devtools/components/Tabs.tsx
@@ -4,8 +4,10 @@ import type { ComponentProps, ReactNode } from "react";
import { Tooltip } from "./Tooltip";
-export interface Tab
- extends Omit, "content"> {
+export interface Tab extends Omit<
+ ComponentProps,
+ "content"
+> {
value: string;
title: string;
richTitle?: ReactNode;
diff --git a/tools/liveblocks-devtools/src/devtools/components/Tooltip.tsx b/tools/liveblocks-devtools/src/devtools/components/Tooltip.tsx
index f5e65890ba6..efb06a6e685 100644
--- a/tools/liveblocks-devtools/src/devtools/components/Tooltip.tsx
+++ b/tools/liveblocks-devtools/src/devtools/components/Tooltip.tsx
@@ -3,7 +3,8 @@ import cx from "classnames";
import { forwardRef, type ReactNode } from "react";
export interface Props
- extends RadixTooltip.TooltipProps,
+ extends
+ RadixTooltip.TooltipProps,
Omit {
content: ReactNode;
}
diff --git a/tools/liveblocks-devtools/src/devtools/components/Tree.tsx b/tools/liveblocks-devtools/src/devtools/components/Tree.tsx
index 3e521327ed7..8b623ceec37 100644
--- a/tools/liveblocks-devtools/src/devtools/components/Tree.tsx
+++ b/tools/liveblocks-devtools/src/devtools/components/Tree.tsx
@@ -187,13 +187,15 @@ type TreeProps = Pick<
> &
ArboristTreeProps;
-interface RowProps
- extends ComponentProps<"div"> {
+interface RowProps<
+ TTreeNode extends DevTools.TreeNode,
+> extends ComponentProps<"div"> {
node: NodeApi;
}
-interface YLogsRowProps
- extends ComponentProps<"div"> {
+interface YLogsRowProps<
+ TTreeNode extends YLogsTreeNode,
+> extends ComponentProps<"div"> {
node: NodeApi;
}
@@ -501,12 +503,14 @@ function summarize(node: DevTools.TreeNode): string {
);
case "LiveList":
- return `${node.payload.length} item${node.payload.length !== 1 ? "s" : ""
- }`;
+ return `${node.payload.length} item${
+ node.payload.length !== 1 ? "s" : ""
+ }`;
case "LiveMap":
- return `${node.payload.length} ${node.payload.length !== 1 ? "entries" : "entry"
- }`;
+ return `${node.payload.length} ${
+ node.payload.length !== 1 ? "entries" : "entry"
+ }`;
case "User":
return wrapObject(
@@ -681,9 +685,9 @@ function Row({
"row text-dark-400 dark:text-light-400 group flex h-full items-center gap-2 pr-2",
isSelected
? [
- background(node.data),
- "tree-focus:text-light-0 bg-light-100 dark:bg-dark-100 hover:bg-light-200 dark:hover:bg-dark-200",
- ]
+ background(node.data),
+ "tree-focus:text-light-0 bg-light-100 dark:bg-dark-100 hover:bg-light-200 dark:hover:bg-dark-200",
+ ]
: isWithinSelectedParent
? "hover:bg-light-100 dark:hover:bg-dark-100 tree-focus:bg-light-100 dark:tree-focus:bg-dark-100 hover:tree-focus:bg-light-200 dark:tree-focus:hover:bg-dark-200"
: "hover:bg-light-100 dark:hover:bg-dark-100"
@@ -725,11 +729,11 @@ function Row({
className={cx(
USE_GRID_LAYOUT
? [
- "grid min-w-0 flex-1 items-center gap-[inherit]",
- isOpen
- ? "grid-cols-[1fr]"
- : "grid-cols-[minmax(0,1fr)_calc(var(--width)_*_0.4)]",
- ]
+ "grid min-w-0 flex-1 items-center gap-[inherit]",
+ isOpen
+ ? "grid-cols-[1fr]"
+ : "grid-cols-[minmax(0,1fr)_calc(var(--width)_*_0.4)]",
+ ]
: "flex min-w-0 flex-1 items-center gap-[inherit]"
)}
>
@@ -757,9 +761,9 @@ function YLogsRow({
"row text-dark-400 dark:text-light-400 group flex h-full items-center gap-2 pr-2",
isSelected
? [
- yLogsBackground(node.data),
- "tree-focus:text-light-0 bg-light-100 dark:bg-dark-100 hover:bg-light-200 dark:hover:bg-dark-200",
- ]
+ yLogsBackground(node.data),
+ "tree-focus:text-light-0 bg-light-100 dark:bg-dark-100 hover:bg-light-200 dark:hover:bg-dark-200",
+ ]
: isWithinSelectedParent
? "hover:bg-light-100 dark:hover:bg-dark-100 tree-focus:bg-light-100 dark:tree-focus:bg-dark-100 hover:tree-focus:bg-light-200 dark:tree-focus:hover:bg-dark-200"
: "hover:bg-light-100 dark:hover:bg-dark-100"
@@ -789,11 +793,11 @@ function YLogsRow({
className={cx(
USE_GRID_LAYOUT
? [
- "grid min-w-0 flex-1 items-center gap-[inherit]",
- isOpen
- ? "grid-cols-[1fr]"
- : "grid-cols-[minmax(0,1fr)_calc(var(--width)_*_0.4)]",
- ]
+ "grid min-w-0 flex-1 items-center gap-[inherit]",
+ isOpen
+ ? "grid-cols-[1fr]"
+ : "grid-cols-[minmax(0,1fr)_calc(var(--width)_*_0.4)]",
+ ]
: "flex min-w-0 flex-1 items-center gap-[inherit]"
)}
>
@@ -1585,16 +1589,16 @@ function presenceChildAccessor(
value === undefined
? []
: [
- makeJsonNode(
- `${node.id.substring(SPECIAL_HACK_PREFIX.length)}`,
- // ^^^^^^^^^^^^^^^^^^^
- // Undo the "special behavior" for the
- // subnodes, making them "normal Json" nodes
- // that aren't expandable
- key,
- value
- ),
- ]
+ makeJsonNode(
+ `${node.id.substring(SPECIAL_HACK_PREFIX.length)}`,
+ // ^^^^^^^^^^^^^^^^^^^
+ // Undo the "special behavior" for the
+ // subnodes, making them "normal Json" nodes
+ // that aren't expandable
+ key,
+ value
+ ),
+ ]
);
}
}
@@ -1858,7 +1862,7 @@ function collectYNode(
case "Y.Text":
case "Y.XmlText":
case "Y.XmlElement":
- case "Y.XmlFragment":
+ case "Y.XmlFragment": {
let isIndirectMatch = false;
for (const childNode of node.payload) {
if (
@@ -1871,6 +1875,7 @@ function collectYNode(
indirectMatches.add(node.id);
}
return isIndirectMatch;
+ }
}
}
}
diff --git a/tools/liveblocks-devtools/src/devtools/contexts/CurrentRoom.tsx b/tools/liveblocks-devtools/src/devtools/contexts/CurrentRoom.tsx
index f2afb2ed337..493da84972f 100644
--- a/tools/liveblocks-devtools/src/devtools/contexts/CurrentRoom.tsx
+++ b/tools/liveblocks-devtools/src/devtools/contexts/CurrentRoom.tsx
@@ -377,7 +377,7 @@ export function useCurrentRoomId(): string | null {
}
export function getRoom(roomId: string | null): Room | null {
- return roomId ? roomsById.get(roomId) ?? null : null;
+ return roomId ? (roomsById.get(roomId) ?? null) : null;
}
export function useSetCurrentRoomId(): (roomId: string) => void {
diff --git a/tools/liveblocks-devtools/src/devtools/index.tsx b/tools/liveblocks-devtools/src/devtools/index.tsx
index 995bbdc8b0b..f6f04251a55 100644
--- a/tools/liveblocks-devtools/src/devtools/index.tsx
+++ b/tools/liveblocks-devtools/src/devtools/index.tsx
@@ -7,8 +7,8 @@ void browser.devtools.panels.create(
"Liveblocks",
"",
// See: https://github.com/PlasmoHQ/plasmo/issues/106#issuecomment-1188539625
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
- liveblocksPanelHTML.split("/").pop()!
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
+ liveblocksPanelHTML.split("/").pop()
);
function Page() {
diff --git a/tools/liveblocks-devtools/src/devtools/panel.tsx b/tools/liveblocks-devtools/src/devtools/panel.tsx
index 20fe448ddf5..9a944bae6d5 100644
--- a/tools/liveblocks-devtools/src/devtools/panel.tsx
+++ b/tools/liveblocks-devtools/src/devtools/panel.tsx
@@ -263,5 +263,5 @@ function PanelApp() {
);
}
-const root = createRoot(document.getElementById("root")!);
+const root = createRoot(document.getElementById("root"));
root.render();
diff --git a/tools/liveblocks-devtools/src/devtools/tabs/yjs/to-y-node.ts b/tools/liveblocks-devtools/src/devtools/tabs/yjs/to-y-node.ts
index 63b2fb1e194..4b39d909ca0 100644
--- a/tools/liveblocks-devtools/src/devtools/tabs/yjs/to-y-node.ts
+++ b/tools/liveblocks-devtools/src/devtools/tabs/yjs/to-y-node.ts
@@ -56,18 +56,18 @@ export type YContentBinaryNode = {
export type YContentFormatNode = {
type: "Y.ContentFormat";
data: {
- [key: string]: Object;
+ [key: string]: object;
};
};
export type YContentEmbedNode = {
type: "Y.ContentEmbed";
- data: Object;
+ data: object;
};
export type YContentAnyNode = {
type: "Y.ContentAny";
- data: (Number | Object | Boolean | Array | String)[];
+ data: (number | object | boolean | Array | string)[];
};
export type YAbstractTypeNode =
diff --git a/tools/liveblocks-devtools/src/devtools/tabs/yjs/to-yjs-tree-node.ts b/tools/liveblocks-devtools/src/devtools/tabs/yjs/to-yjs-tree-node.ts
index 4a344f10b57..6f10b2bef82 100644
--- a/tools/liveblocks-devtools/src/devtools/tabs/yjs/to-yjs-tree-node.ts
+++ b/tools/liveblocks-devtools/src/devtools/tabs/yjs/to-yjs-tree-node.ts
@@ -53,7 +53,7 @@ export type YContentEmbedTreeNode = {
type: YContentEmbedNode["type"];
id: string;
key: string;
- payload: Object;
+ payload: object;
};
export type YContentBinaryTreeNode = {
@@ -67,14 +67,14 @@ export type YContentFormatTreeNode = {
type: YContentFormatNode["type"];
id: string;
key: string;
- payload: Object;
+ payload: object;
};
export type YContentAnyTreeNode = {
type: YContentAnyNode["type"];
id: string;
key: string;
- payload: (Number | Object | Boolean | Array | String)[];
+ payload: (number | object | boolean | Array | string)[];
};
export type YContentTreeNode =
diff --git a/tools/liveblocks-devtools/src/devtools/tabs/yjs/yflow/YItemNode.tsx b/tools/liveblocks-devtools/src/devtools/tabs/yjs/yflow/YItemNode.tsx
index 5c8b4f2f185..4424e33bb7e 100644
--- a/tools/liveblocks-devtools/src/devtools/tabs/yjs/yflow/YItemNode.tsx
+++ b/tools/liveblocks-devtools/src/devtools/tabs/yjs/yflow/YItemNode.tsx
@@ -22,38 +22,28 @@ function YItemNode({ selected, data }: NodeProps) {
switch (true) {
case data.item.content instanceof Y.ContentDeleted:
- component = (
-
- );
+ component = ;
break;
case data.item.content instanceof Y.ContentString:
- component = (
-
- );
+ component = ;
break;
case data.item.content instanceof Y.ContentFormat:
- component = (
-
- );
+ component = ;
break;
case data.item.content instanceof Y.ContentJSON:
- component = ;
+ component = ;
break;
case data.item.content instanceof Y.ContentAny:
- component = ;
+ component = ;
break;
case data.item.content instanceof Y.ContentType:
- component = ;
+ component = ;
break;
case data.item.content instanceof Y.ContentBinary:
- component = (
-
- );
+ component = ;
break;
case data.item.content instanceof Y.ContentEmbed:
- component = (
-
- );
+ component = ;
break;
default: {
component = ;
diff --git a/tools/liveblocks-devtools/src/lib/stringify.ts b/tools/liveblocks-devtools/src/lib/stringify.ts
index 94e1d9e1f6a..78c10010ebe 100644
--- a/tools/liveblocks-devtools/src/lib/stringify.ts
+++ b/tools/liveblocks-devtools/src/lib/stringify.ts
@@ -20,7 +20,7 @@ export function wrapObject(values?: string) {
return values ? `{ ${values} }` : "{}";
}
-type YjsContentData = Number | Object | Boolean | Array | String;
+type YjsContentData = number | object | boolean | Array | string;
export function stringify(
value?: Json | YjsContentData | YjsContentData[],
diff --git a/tools/liveblocks-devtools/src/lib/ydoc.ts b/tools/liveblocks-devtools/src/lib/ydoc.ts
index 88dc38feddc..9309be002d1 100644
--- a/tools/liveblocks-devtools/src/lib/ydoc.ts
+++ b/tools/liveblocks-devtools/src/lib/ydoc.ts
@@ -1,4 +1,3 @@
-/* eslint-disable eqeqeq */
import type { Edge, Node } from "reactflow";
import { MarkerType } from "reactflow";
import * as Y from "yjs";