diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f0688f645a..d9e8408e2c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,22 +17,3 @@ repos: rev: v5.0.0 hooks: - id: end-of-file-fixer - - # TODO(oleg): fix ESLint warnings - # - repo: https://github.com/pre-commit/mirrors-eslint - # rev: 'v8.31.0' - # hooks: - # - id: eslint - # name: ESLint - # entry: eslint --fix --config frontend/.eslintrc --ignore-path frontend/.eslintignore - # language: node - # pass_filenames: false - # cwd: "frontend/" - # additional_dependencies: - # - eslint@8.31.0 - # - eslint-config-prettier@8.10.0 - # - eslint-plugin-i18n@2.4.0 - # - eslint-plugin-prettier@4.2.1 - # - eslint-plugin-simple-import-sort@10.0.0 - # - '@typescript-eslint/eslint-plugin@5.48.1' - # - '@typescript-eslint/parser@5.48.1' diff --git a/frontend/.eslintignore b/frontend/.eslintignore deleted file mode 100644 index 9016074a05..0000000000 --- a/frontend/.eslintignore +++ /dev/null @@ -1,12 +0,0 @@ -node_modules -build -server.js -src/locale -src/types -src/setupProxy.js -webpack/** -webpack/env.js -webpack/prod.js -public -staticServer.js -webpack.config.js diff --git a/frontend/.eslintrc b/frontend/.eslintrc deleted file mode 100644 index 0903c46059..0000000000 --- a/frontend/.eslintrc +++ /dev/null @@ -1,34 +0,0 @@ -{ - "root": true, - "parser": "@typescript-eslint/parser", - "plugins": [ - "@typescript-eslint", - "i18n", - "simple-import-sort" - ], - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended", - "prettier", - "plugin:prettier/recommended" - ], - "rules": { - "i18n/no-russian-character": 1, - "simple-import-sort/imports": [ - "error", - { - "groups": [ - ["^react", "lodash", "^\\w", "^@?\\w"], - ["^components", "^layouts"], - ["^consts", "^hooks", "^libs", "^routes", "^services","^types"], - ["^App", "^pages"], - ["^\\./(?=.*/)(?!/?$)", "^\\.(?!/?$)", "^\\./?$"], - ["./constants/."], - ["./definitions/.", "./types"], - ["^.+\\.svg", "^.+\\.png$", "^.+\\.jpg", "^.+\\.s?css$"] - ] - } - ] - } -} diff --git a/frontend/.husky/pre-commit b/frontend/.husky/pre-commit new file mode 100644 index 0000000000..c72b09fe63 --- /dev/null +++ b/frontend/.husky/pre-commit @@ -0,0 +1,2 @@ +cd frontend +npm run precommit diff --git a/frontend/eslint.config.cjs b/frontend/eslint.config.cjs new file mode 100644 index 0000000000..3cfe1c41e4 --- /dev/null +++ b/frontend/eslint.config.cjs @@ -0,0 +1,71 @@ +const { defineConfig, globalIgnores } = require('eslint/config'); +const i18N = require('eslint-plugin-i18n'); +const simpleImportSort = require('eslint-plugin-simple-import-sort'); +const { FlatCompat } = require('@eslint/eslintrc'); +const js = require('@eslint/js'); +const typescriptEslint = require('@typescript-eslint/eslint-plugin'); +const tsParser = require('@typescript-eslint/parser'); + +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all, +}); + +const BASE_CONFIG = { + extends: compat.extends( + 'eslint:recommended', + 'plugin:@typescript-eslint/eslint-recommended', + 'plugin:@typescript-eslint/recommended', + 'prettier', + 'plugin:prettier/recommended' + ), + + plugins: { + '@typescript-eslint': typescriptEslint, + i18n: i18N, + 'simple-import-sort': simpleImportSort, + }, + + languageOptions: { + parser: tsParser, + }, + + rules: { + 'i18n/no-russian-character': 1, + + 'simple-import-sort/imports': [ + 'error', + { + groups: [ + ['^react', 'lodash', '^\\w', '^@?\\w'], + ['^components', '^layouts'], + ['^consts', '^hooks', '^libs', '^routes', '^services', '^types'], + ['^App', '^pages'], + ['^\\./(?=.*/)(?!/?$)', '^\\.(?!/?$)', '^\\./?$'], + ['./constants/.'], + ['./definitions/.', './types'], + ['^.+\\.svg', '^.+\\.png$', '^.+\\.jpg', '^.+\\.s?css$'], + ], + }, + ], + }, +}; + +module.exports = defineConfig([ + globalIgnores([ + 'node_modules', + 'build', + 'server.js', + 'src/locale', + 'src/types', + 'src/setupProxy.js', + 'webpack/**/*', + 'webpack/env.js', + 'webpack/prod.js', + 'public', + 'staticServer.js', + 'webpack.config.js', + ]), + { ...BASE_CONFIG }, +]); diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 3795a57c18..55242f45f0 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -49,6 +49,8 @@ "@babel/preset-typescript": "^7.26.0", "@babel/register": "^7.25.9", "@cfaester/enzyme-adapter-react-18": "^0.8.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "^9.28.0", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.15", "@rtk-query/codegen-openapi": "^2.0.0", "@svgr/webpack": "^6.5.1", @@ -67,8 +69,8 @@ "@types/react-redux": "^7.1.34", "@types/react-router-dom": "^5.3.3", "@types/react-test-renderer": "^18.3.0", - "@typescript-eslint/eslint-plugin": "^5.48.1", - "@typescript-eslint/parser": "^5.48.1", + "@typescript-eslint/eslint-plugin": "^8.33.1", + "@typescript-eslint/parser": "^8.33.1", "@webpack-cli/serve": "^2.0.5", "babel-loader": "^9.2.1", "babel-preset-minify": "^0.5.2", @@ -77,26 +79,28 @@ "cross-env": "^7.0.3", "css-loader": "^6.7.3", "enzyme": "^3.11.0", - "eslint": "^8.31.0", - "eslint-config-prettier": "^8.6.0", + "eslint": "^9.28.0", + "eslint-config-prettier": "^10.1.5", "eslint-plugin-i18n": "^2.4.0", - "eslint-plugin-prettier": "^4.2.1", - "eslint-plugin-simple-import-sort": "^10.0.0", + "eslint-plugin-prettier": "^5.4.1", + "eslint-plugin-simple-import-sort": "^12.1.1", "favicons": "^7.2.0", "favicons-webpack-plugin": "^6.0.1", "file-loader": "^6.2.0", "html-webpack-plugin": "^5.6.3", "http-proxy-middleware": "^2.0.6", + "husky": "^9.1.7", "identity-obj-proxy": "^3.0.0", "jest": "^29.7.0", "jest-styled-components": "^7.2.0", + "lint-staged": "^16.1.2", "loader-utils": "^3.3.1", "mini-css-extract-plugin": "^2.9.2", "npx": "^10.2.2", "postcss": "^8.4.49", "postcss-loader": "^7.0.2", "postcss-preset-env": "7.8.3", - "prettier": "^2.8.2", + "prettier": "^3.5.3", "react-dev-utils": "^12.0.1", "react-refresh": "^0.14.2", "react-test-renderer": "^18.3.1", @@ -2552,10 +2556,11 @@ "peer": true }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", - "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", "dev": true, + "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.4.3" }, @@ -2578,16 +2583,55 @@ "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint/config-array": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", + "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.2.tgz", + "integrity": "sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.14.0.tgz", + "integrity": "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==", + "dev": true, + "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/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "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", @@ -2595,7 +2639,7 @@ "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" @@ -2606,6 +2650,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -2621,18 +2666,17 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "dev": true, + "license": "Python-2.0" }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -2643,6 +2687,7 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -2654,27 +2699,44 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/@eslint/js": { + "version": "9.28.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.28.0.tgz", + "integrity": "sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://eslint.org/donate" } }, - "node_modules/@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", "dev": true, + "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" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.1.tgz", + "integrity": "sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.14.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@exodus/schemasafe": { @@ -2736,19 +2798,42 @@ "react-hook-form": "^7.0.0" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "deprecated": "Use @eslint/config-array instead", + "node_modules/@humanfs/core": { + "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" + } + }, + "node_modules/@humanfs/node": { + "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": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" }, "engines": { - "node": ">=10.10.0" + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, "node_modules/@humanwhocodes/module-importer": { @@ -2764,12 +2849,19 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true + "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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, "node_modules/@img/sharp-darwin-arm64": { "version": "0.33.5", @@ -4020,6 +4112,19 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/@pkgr/core": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.7.tgz", + "integrity": "sha512-YLT9Zo3oNPJoBjBc4q8G2mjU4tqIbf5CEOORbUUr48dCD9q3umJ3IPlVqOqDakPfd2HuwccBaqlGhN4Gmr5OWg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { "version": "0.5.15", "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.15.tgz", @@ -4148,21 +4253,6 @@ "rtk-query-codegen-openapi": "lib/bin/cli.mjs" } }, - "node_modules/@rtk-query/codegen-openapi/node_modules/prettier": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", - "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", - "dev": true, - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, "node_modules/@rtk-query/codegen-openapi/node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -5038,12 +5128,6 @@ "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", "dev": true }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true - }, "node_modules/@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", @@ -5124,129 +5208,159 @@ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", - "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.33.1.tgz", + "integrity": "sha512-TDCXj+YxLgtvxvFlAvpoRv9MAncDLBV2oT9Bd7YBGC/b/sEURoOYuIwLI99rjWOfY3QtDzO+mk0n4AmdFExW8A==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/type-utils": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.33.1", + "@typescript-eslint/type-utils": "8.33.1", + "@typescript-eslint/utils": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@typescript-eslint/parser": "^8.33.1", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "dev": true, - "bin": { - "semver": "bin/semver.js" - }, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">= 4" } }, "node_modules/@typescript-eslint/parser": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", - "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.33.1.tgz", + "integrity": "sha512-qwxv6dq682yVvgKKp2qWwLgRbscDAYktPptK4JPojCwwi3R9cwrvIxS4lvBpzmcqzR4bdn54Z0IG1uHFskW4dA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/scope-manager": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/typescript-estree": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", "debug": "^4.3.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.33.1.tgz", + "integrity": "sha512-DZR0efeNklDIHHGRpMpR5gJITQpu6tLr9lDJnKdONTC7vvzOlLAG/wcfxcdxEWrbiZApcoBCzXqU/Z458Za5Iw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.33.1", + "@typescript-eslint/types": "^8.33.1", + "debug": "^4.3.4" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.1.tgz", + "integrity": "sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.33.1.tgz", + "integrity": "sha512-STAQsGYbHCF0/e+ShUQ4EatXQ7ceh3fBCXkNU7/MZVKulrlq1usH7t2FhxvCpuCi5O5oi1vmVaAjrGeL71OK1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", - "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.33.1.tgz", + "integrity": "sha512-1cG37d9xOkhlykom55WVwG2QRNC7YXlxMaMzqw2uPeJixBFfKWZgaP/hjAObqMN/u3fr5BrTwTnc31/L9jQ2ww==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", + "@typescript-eslint/typescript-estree": "8.33.1", + "@typescript-eslint/utils": "8.33.1", "debug": "^4.3.4", - "tsutils": "^3.21.0" + "ts-api-utils": "^2.1.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", + "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", "dev": true, + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -5254,37 +5368,66 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.1.tgz", + "integrity": "sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", + "@typescript-eslint/project-service": "8.33.1", + "@typescript-eslint/tsconfig-utils": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", "debug": "^4.3.4", - "globby": "^11.1.0", + "fast-glob": "^3.3.2", "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/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", + "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.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -5293,65 +5436,59 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.33.1.tgz", + "integrity": "sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/typescript-estree": "8.33.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.1.tgz", + "integrity": "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" + "@typescript-eslint/types": "8.33.1", + "eslint-visitor-keys": "^4.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } }, "node_modules/@webassemblyjs/ast": { "version": "1.12.1", @@ -5596,6 +5733,7 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -6994,6 +7132,93 @@ "node": ">=0.10.0" } }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -7394,10 +7619,11 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "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", @@ -7854,10 +8080,11 @@ } }, "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "dev": true, + "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -8114,18 +8341,6 @@ "node": ">=6" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/dom-accessibility-api": { "version": "0.5.16", "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", @@ -8337,6 +8552,19 @@ "node": ">=4" } }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/enzyme": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-3.11.0.tgz", @@ -8578,69 +8806,78 @@ } }, "node_modules/eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "version": "9.28.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.28.0.tgz", + "integrity": "sha512-ocgh41VhRlf9+fVpe7QKzwLj9c92fDiqOj8Y3Sd4/ZmVA4Btx4PlUYPq4pp9JDyupkf1upbEXecxL2mwNV7jPQ==", "dev": true, + "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.1", - "@humanwhocodes/config-array": "^0.13.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.20.0", + "@eslint/config-helpers": "^0.2.1", + "@eslint/core": "^0.14.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.28.0", + "@eslint/plugin-kit": "^0.3.1", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "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.3.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.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", "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-config-prettier": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", - "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", + "version": "10.1.5", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.5.tgz", + "integrity": "sha512-zc1UmCpNltmVY34vuLRV61r1K27sWuX39E+uyUnY8xS2Bex88VV9cugG+UZbRSRGtGyFboj+D8JODyme1plMpw==", "dev": true, + "license": "MIT", "bin": { "eslint-config-prettier": "bin/cli.js" }, + "funding": { + "url": "https://opencollective.com/eslint-config-prettier" + }, "peerDependencies": { "eslint": ">=7.0.0" } @@ -8655,31 +8892,42 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", - "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.4.1.tgz", + "integrity": "sha512-9dF+KuU/Ilkq27A8idRP7N2DH8iUR6qXcjF3FR2wETY21PZdBrIjwCau8oboyGj9b7etWmTGEeM8e7oOed6ZWg==", "dev": true, + "license": "MIT", "dependencies": { - "prettier-linter-helpers": "^1.0.0" + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.11.7" }, "engines": { - "node": ">=12.0.0" + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" }, "peerDependencies": { - "eslint": ">=7.28.0", - "prettier": ">=2.0.0" + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", + "prettier": ">=3.0.0" }, "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, "eslint-config-prettier": { "optional": true } } }, "node_modules/eslint-plugin-simple-import-sort": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-10.0.0.tgz", - "integrity": "sha512-AeTvO9UCMSNzIHRkg8S6c3RPy5YEwKWSQPx3DYghLedo2ZQxowPFLGDN1AZ2evfg6r6mjBSZSLxLFsWSu3acsw==", + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.1.tgz", + "integrity": "sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==", "dev": true, + "license": "MIT", "peerDependencies": { "eslint": ">=5.0.0" } @@ -8724,23 +8972,31 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", + "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.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/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -8751,6 +9007,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -8767,63 +9024,38 @@ "node": ">=10.13.0" } }, - "node_modules/eslint/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/eslint/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/eslint" } }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, + "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" @@ -9164,15 +9396,16 @@ } }, "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "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": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/file-loader": { @@ -9388,24 +9621,25 @@ } }, "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "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.3", - "rimraf": "^3.0.2" + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16" } }, "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" }, "node_modules/follow-redirects": { "version": "1.15.9", @@ -9723,6 +9957,19 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-east-asian-width": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", + "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", @@ -10332,6 +10579,22 @@ "ms": "^2.0.0" } }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "license": "MIT", + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/hyperdyperid": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", @@ -10873,15 +11136,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/is-plain-obj": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", @@ -12099,7 +12353,8 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", @@ -12146,6 +12401,7 @@ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, + "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } @@ -12214,6 +12470,193 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "node_modules/lint-staged": { + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.1.2.tgz", + "integrity": "sha512-sQKw2Si2g9KUZNY3XNvRuDq4UJqpHwF0/FQzZR2M7I5MvtpWvibikCjUVJzZdGE0ByurEl3KQNvsGetd1ty1/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.4.1", + "commander": "^14.0.0", + "debug": "^4.4.1", + "lilconfig": "^3.1.3", + "listr2": "^8.3.3", + "micromatch": "^4.0.8", + "nano-spawn": "^1.0.2", + "pidtree": "^0.6.0", + "string-argv": "^0.3.2", + "yaml": "^2.8.0" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": ">=20.17" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/lint-staged/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/commander": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.0.tgz", + "integrity": "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/lint-staged/node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lint-staged/node_modules/yaml": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", + "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, + "node_modules/listr2": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.3.3.tgz", + "integrity": "sha512-LWzX2KsqcB1wqQ4AHgYb4RsDXauQiqhjLk+6hjbaeHG4zpjjVAB6wC/gz6X0l+Du1cN3pUB5ZlrvTbhGSNnUQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -12302,6 +12745,160 @@ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -12499,6 +13096,19 @@ "node": ">=6" } }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -12590,6 +13200,19 @@ "multicast-dns": "cli.js" } }, + "node_modules/nano-spawn": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nano-spawn/-/nano-spawn-1.0.2.tgz", + "integrity": "sha512-21t+ozMQDAL/UGgQVBbZ/xXvNO10++ZPuTmKRO8k9V3AClVRht49ahtDjfY8l1q6nSHOrE5ASfthzH3ol6R/hg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/nano-spawn?sponsor=1" + } + }, "node_modules/nanoclone": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz", @@ -12618,12 +13241,6 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, "node_modules/nearley": { "version": "2.20.1", "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz", @@ -18403,6 +19020,19 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "license": "MIT", + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", @@ -19677,15 +20307,16 @@ } }, "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", + "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", "dev": true, + "license": "MIT", "bin": { - "prettier": "bin-prettier.js" + "prettier": "bin/prettier.cjs" }, "engines": { - "node": ">=10.13.0" + "node": ">=14" }, "funding": { "url": "https://github.com/prettier/prettier?sponsor=1" @@ -20740,6 +21371,52 @@ "node": ">=10" } }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -20768,21 +21445,12 @@ "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } + "license": "MIT" }, "node_modules/rst-selector-parser": { "version": "2.2.3", @@ -21441,6 +22109,49 @@ "node": ">=6" } }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -21573,6 +22284,16 @@ "safe-buffer": "~5.2.0" } }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.19" + } + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -21953,6 +22674,22 @@ "url": "https://github.com/Mermade/oas-kit?sponsor=1" } }, + "node_modules/synckit": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.8.tgz", + "integrity": "sha512-+XZ+r1XGIJGeQk3VvXhT6xx/VpbHsRzsTkGgF6E5RX9TTXD0118l87puaEBZ566FhqblC6U0d4XnubznJDm30A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.2.4" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/synckit" + } + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -22179,6 +22916,19 @@ "tslib": "2" } }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, "node_modules/ts-jest": { "version": "29.2.5", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.5.tgz", @@ -22287,27 +23037,6 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==" }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 3191ba54c0..f4de75c603 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -15,7 +15,9 @@ "eslint-fix": "eslint ./src --ext .js,.jsx,.ts,.tsx --fix", "test": "jest", "test:update-snapshots": "jest -u", - "generate-api": "npx @rtk-query/codegen-openapi openapi-config.ts" + "generate-api": "npx @rtk-query/codegen-openapi openapi-config.ts", + "prepare": "cd .. && husky frontend/.husky", + "precommit": "lint-staged" }, "devDependencies": { "@babel/cli": "^7.25.9", @@ -27,6 +29,8 @@ "@babel/preset-typescript": "^7.26.0", "@babel/register": "^7.25.9", "@cfaester/enzyme-adapter-react-18": "^0.8.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "^9.28.0", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.15", "@rtk-query/codegen-openapi": "^2.0.0", "@svgr/webpack": "^6.5.1", @@ -45,8 +49,8 @@ "@types/react-redux": "^7.1.34", "@types/react-router-dom": "^5.3.3", "@types/react-test-renderer": "^18.3.0", - "@typescript-eslint/eslint-plugin": "^5.48.1", - "@typescript-eslint/parser": "^5.48.1", + "@typescript-eslint/eslint-plugin": "^8.33.1", + "@typescript-eslint/parser": "^8.33.1", "@webpack-cli/serve": "^2.0.5", "babel-loader": "^9.2.1", "babel-preset-minify": "^0.5.2", @@ -55,26 +59,28 @@ "cross-env": "^7.0.3", "css-loader": "^6.7.3", "enzyme": "^3.11.0", - "eslint": "^8.31.0", - "eslint-config-prettier": "^8.6.0", + "eslint": "^9.28.0", + "eslint-config-prettier": "^10.1.5", "eslint-plugin-i18n": "^2.4.0", - "eslint-plugin-prettier": "^4.2.1", - "eslint-plugin-simple-import-sort": "^10.0.0", + "eslint-plugin-prettier": "^5.4.1", + "eslint-plugin-simple-import-sort": "^12.1.1", "favicons": "^7.2.0", "favicons-webpack-plugin": "^6.0.1", "file-loader": "^6.2.0", "html-webpack-plugin": "^5.6.3", "http-proxy-middleware": "^2.0.6", + "husky": "^9.1.7", "identity-obj-proxy": "^3.0.0", "jest": "^29.7.0", "jest-styled-components": "^7.2.0", + "lint-staged": "^16.1.2", "loader-utils": "^3.3.1", "mini-css-extract-plugin": "^2.9.2", "npx": "^10.2.2", "postcss": "^8.4.49", "postcss-loader": "^7.0.2", "postcss-preset-env": "7.8.3", - "prettier": "^2.8.2", + "prettier": "^3.5.3", "react-dev-utils": "^12.0.1", "react-refresh": "^0.14.2", "react-test-renderer": "^18.3.1", @@ -121,5 +127,11 @@ "react-string-replace": "^1.1.1", "redux": "^5.0.1", "yup": "^0.32.11" + }, + "lint-staged": { + "*.{js,jsx,ts,tsx}": [ + "eslint --fix --max-warnings=0 --no-warn-ignored", + "git add" + ] } } diff --git a/frontend/src/App/Login/EnterpriseLogin/index.tsx b/frontend/src/App/Login/EnterpriseLogin/index.tsx index 07b76e1b3f..7cb9b530af 100644 --- a/frontend/src/App/Login/EnterpriseLogin/index.tsx +++ b/frontend/src/App/Login/EnterpriseLogin/index.tsx @@ -6,11 +6,11 @@ import { Box, NavigateLink, SpaceBetween } from 'components'; import { UnauthorizedLayout } from 'layouts/UnauthorizedLayout'; import { ROUTES } from 'routes'; -import { useGetEntraInfoQuery, useGetOktaInfoQuery, useGetGoogleInfoQuery } from 'services/auth'; +import { useGetEntraInfoQuery, useGetGoogleInfoQuery, useGetOktaInfoQuery } from 'services/auth'; import { LoginByEntraID } from '../EntraID/LoginByEntraID'; -import { LoginByOkta } from '../LoginByOkta'; import { LoginByGoogle } from '../LoginByGoogle'; +import { LoginByOkta } from '../LoginByOkta'; import { LoginByTokenForm } from '../LoginByTokenForm'; import styles from './styles.module.scss'; diff --git a/frontend/src/components/FileUploader/FileEntry/index.tsx b/frontend/src/components/FileUploader/FileEntry/index.tsx index bf002f3589..21ba14a2f7 100644 --- a/frontend/src/components/FileUploader/FileEntry/index.tsx +++ b/frontend/src/components/FileUploader/FileEntry/index.tsx @@ -22,7 +22,6 @@ export const FileEntry: React.FC = ({ file, showImage = false, truncateL }; reader.readAsDataURL(file); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const ext = file.name.split('.').pop()!; const displayFileName = file.name.length - ext.length - 1 > truncateLength ? `${file.name.slice(0, truncateLength)}... .${ext}` : file.name; @@ -46,6 +45,7 @@ export const FileEntry: React.FC = ({ file, showImage = false, truncateL {displayFileName} + {/* eslint-disable-next-line no-constant-binary-expression */} {false && ( <> {i18nStrings ? i18nStrings.numberOfBytes(fileSize) : `${fileSize} bytes`} diff --git a/frontend/src/components/Tabs/index.tsx b/frontend/src/components/Tabs/index.tsx index 4e5bd508c1..e51196db9c 100644 --- a/frontend/src/components/Tabs/index.tsx +++ b/frontend/src/components/Tabs/index.tsx @@ -31,7 +31,7 @@ export const Tabs: React.FC = ({ className, withNavigation, onChange, ac const onChangeTab: TabsProps['onChange'] = (event) => { if (withNavigation) { const { detail } = event; - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + navigate(detail.activeTabHref!); } diff --git a/frontend/src/components/form/Checkbox/index.tsx b/frontend/src/components/form/Checkbox/index.tsx index 387d8c2ea8..ac64f8f54c 100644 --- a/frontend/src/components/form/Checkbox/index.tsx +++ b/frontend/src/components/form/Checkbox/index.tsx @@ -43,7 +43,7 @@ export const FormCheckbox = ({ checked={value} onChange={(event) => { onChange(event.detail.checked); - onChangeProp && onChangeProp(event); + onChangeProp?.(event); }} > {checkboxLabel} diff --git a/frontend/src/components/form/CodeEditor/index.tsx b/frontend/src/components/form/CodeEditor/index.tsx index 7d9aa15b2b..4d23ea1012 100644 --- a/frontend/src/components/form/CodeEditor/index.tsx +++ b/frontend/src/components/form/CodeEditor/index.tsx @@ -78,7 +78,7 @@ export const FormCodeEditor = ({ ace={ace} onChange={(event) => { onChange(event.detail.value); - onChangeProp && onChangeProp(event); + onChangeProp?.(event); }} themes={{ light: [], dark: [] }} preferences={codeEditorPreferences} diff --git a/frontend/src/components/form/Input/index.tsx b/frontend/src/components/form/Input/index.tsx index 3ccfe8058a..784de33e9b 100644 --- a/frontend/src/components/form/Input/index.tsx +++ b/frontend/src/components/form/Input/index.tsx @@ -51,7 +51,7 @@ export const FormInput = ({ invalid: !!error, onChange: (event) => { onChange(event.detail.value); - onChangeProp && onChangeProp(event); + onChangeProp?.(event); }, })} @@ -62,7 +62,7 @@ export const FormInput = ({ invalid: !!error, onChange: (event) => { onChange(event.detail.value); - onChangeProp && onChangeProp(event); + onChangeProp?.(event); }, }) )} diff --git a/frontend/src/components/form/Multiselect/index.tsx b/frontend/src/components/form/Multiselect/index.tsx index 98a3404d90..93166c010b 100644 --- a/frontend/src/components/form/Multiselect/index.tsx +++ b/frontend/src/components/form/Multiselect/index.tsx @@ -30,7 +30,7 @@ export const FormMultiselect = ({ const onChangeSelect: MultiselectProps['onChange'] = (event) => { const value = event.detail.selectedOptions.map((item) => item.value); onChange(value); - onChangeProp && onChangeProp(event); + onChangeProp?.(event); }; return ( diff --git a/frontend/src/components/form/RadioButtons/index.tsx b/frontend/src/components/form/RadioButtons/index.tsx index 9290b019cd..aa56652d62 100644 --- a/frontend/src/components/form/RadioButtons/index.tsx +++ b/frontend/src/components/form/RadioButtons/index.tsx @@ -26,7 +26,7 @@ export const FormRadioButtons = ({ render={({ field: { onChange, ...fieldRest }, fieldState: { error } }) => { const onChangeSelect: RadioGroupProps['onChange'] = (event) => { onChange(event.detail.value); - onChangeProp && onChangeProp(event); + onChangeProp?.(event); }; return ( diff --git a/frontend/src/components/form/S3BucketSelector/index.tsx b/frontend/src/components/form/S3BucketSelector/index.tsx index 7bc6d574ad..90b930af6e 100644 --- a/frontend/src/components/form/S3BucketSelector/index.tsx +++ b/frontend/src/components/form/S3BucketSelector/index.tsx @@ -63,7 +63,7 @@ export const FormS3BucketSelector = ({ lastValue.current = bucket; onChange(bucket); - onChangeProp && onChangeProp(event); + onChangeProp?.(event); }; return ( diff --git a/frontend/src/components/form/Select/index.tsx b/frontend/src/components/form/Select/index.tsx index 99fcbeb781..b1b5f9b2ea 100644 --- a/frontend/src/components/form/Select/index.tsx +++ b/frontend/src/components/form/Select/index.tsx @@ -29,7 +29,7 @@ export const FormSelect = ({ const onChangeSelect: SelectProps['onChange'] = (event) => { onChange(event.detail.selectedOption.value); - onChangeProp && onChangeProp(event); + onChangeProp?.(event); }; return ( diff --git a/frontend/src/components/form/Textarea/index.tsx b/frontend/src/components/form/Textarea/index.tsx index f9816616df..e34ba2e6b5 100644 --- a/frontend/src/components/form/Textarea/index.tsx +++ b/frontend/src/components/form/Textarea/index.tsx @@ -42,7 +42,7 @@ export const FormTextarea = ({ invalid={!!error} onChange={(event) => { onChange(event.detail.value); - onChangeProp && onChangeProp(event); + onChangeProp?.(event); }} /> diff --git a/frontend/src/components/form/Tiles/index.tsx b/frontend/src/components/form/Tiles/index.tsx index b38c9ffa41..82515115fa 100644 --- a/frontend/src/components/form/Tiles/index.tsx +++ b/frontend/src/components/form/Tiles/index.tsx @@ -13,7 +13,7 @@ export const FormTiles = ({ name, control, onChange: onCh render={({ field: { onChange, ...fieldRest } }) => { const onChangeSelect: TilesProps['onChange'] = (event) => { onChange(event.detail.value); - onChangeProp && onChangeProp(event); + onChangeProp?.(event); }; return ; diff --git a/frontend/src/layouts/AppLayout/TutorialPanel/hooks.ts b/frontend/src/layouts/AppLayout/TutorialPanel/hooks.ts index 911b7b1083..25ee532201 100644 --- a/frontend/src/layouts/AppLayout/TutorialPanel/hooks.ts +++ b/frontend/src/layouts/AppLayout/TutorialPanel/hooks.ts @@ -69,7 +69,6 @@ export const useTutorials = () => { dispatch(updateTutorialPanelState({ billingCompleted: true })); }, []); - // eslint-disable-next-line @typescript-eslint/no-empty-function const startConfigCliTutorial = useCallback(() => {}, [billingUrl]); const finishConfigCliTutorial = useCallback(() => { diff --git a/frontend/src/libs/filters.ts b/frontend/src/libs/filters.ts index bdf1437fe0..425caaaef8 100644 --- a/frontend/src/libs/filters.ts +++ b/frontend/src/libs/filters.ts @@ -26,27 +26,30 @@ export const tokensToRequestParams = ({ tokens: PropertyFilterProps.Query['tokens']; arrayFieldKeys?: RequestParamsKeys[]; }) => { - return tokens.reduce>((acc, token) => { - const propertyKey = token.propertyKey as RequestParamsKeys; + return tokens.reduce>( + (acc, token) => { + const propertyKey = token.propertyKey as RequestParamsKeys; - if (!propertyKey) { - return acc; - } - - if (arrayFieldKeys?.includes(propertyKey)) { - if (Array.isArray(acc[propertyKey])) { - acc[propertyKey].push(token.value); - } else { - acc[propertyKey] = [token.value]; + if (!propertyKey) { + return acc; } - return acc; - } + if (arrayFieldKeys?.includes(propertyKey)) { + if (Array.isArray(acc[propertyKey])) { + acc[propertyKey].push(token.value); + } else { + acc[propertyKey] = [token.value]; + } + + return acc; + } - acc[propertyKey] = token.value; + acc[propertyKey] = token.value; - return acc; - }, {} as Record); + return acc; + }, + {} as Record, + ); }; export const EMPTY_QUERY: PropertyFilterProps.Query = { diff --git a/frontend/src/libs/index.ts b/frontend/src/libs/index.ts index 85b8e6ab96..523923ab4b 100644 --- a/frontend/src/libs/index.ts +++ b/frontend/src/libs/index.ts @@ -8,10 +8,13 @@ import { format, formatDistanceToNowStrict } from 'date-fns'; // eslint-disable-next-line @typescript-eslint/no-explicit-any export function arrayToRecordByKeyName(array: T[], selector: K) { - return array.reduce((acc, item) => { - acc[item[selector]] = item; - return acc; - }, {} as Record); + return array.reduce( + (acc, item) => { + acc[item[selector]] = item; + return acc; + }, + {} as Record, + ); } export function wait(delayInMS: number): Promise { @@ -46,6 +49,7 @@ export const getDateAgoSting = (time: number): string => { if (Date.now() - time < MINUTE * 60 * 24) return formatDistanceToNowStrict(new Date(time), { addSuffix: true }); return format(new Date(time), 'dd/MM/yyyy'); + // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (err) { return ''; } @@ -84,7 +88,6 @@ export const centsToFormattedString = (cents: number, currency?: string): string }; export const riseRouterException = (status = 404, json = 'Not Found'): never => { - // eslint-disable-next-line @typescript-eslint/no-throw-literal throw new Response(json, { status }); }; @@ -100,6 +103,7 @@ export const base64ToArrayBuffer = (base64: string) => { export const isValidUrl = (urlString: string) => { try { return Boolean(new URL(urlString)); + // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (e) { return false; } diff --git a/frontend/src/libs/run.ts b/frontend/src/libs/run.ts index de96c16c30..e49e4c28fa 100644 --- a/frontend/src/libs/run.ts +++ b/frontend/src/libs/run.ts @@ -2,6 +2,7 @@ import { get as _get } from 'lodash'; import { StatusIndicatorProps } from '@cloudscape-design/components'; import { capitalize } from 'libs'; + import { finishedRunStatuses } from '../pages/Runs/constants'; import { IModelExtended } from '../pages/Models/List/types'; @@ -45,7 +46,7 @@ export const getStatusIconColor = ( switch (status) { case 'submitted': case 'pending': - return 'blue'; + return 'blue'; case 'pulling': return 'green'; case 'aborted': diff --git a/frontend/src/pages/Models/Details/index.tsx b/frontend/src/pages/Models/Details/index.tsx index 5638c48401..ad9906d5b1 100644 --- a/frontend/src/pages/Models/Details/index.tsx +++ b/frontend/src/pages/Models/Details/index.tsx @@ -246,9 +246,9 @@ export const ModelDetails: React.FC = () => { {replacedStrings.filter((line, index) => { if ( - languages.includes(line) && + languages.includes(line as string) && typeof replacedStrings[index + 1] !== 'string' && - typeof replacedStrings[index + 1] !== undefined + typeof replacedStrings[index + 1] !== 'undefined' ) { return false; } @@ -270,6 +270,8 @@ export const ModelDetails: React.FC = () => { textAreaElement.style.height = textAreaElement.scrollHeight + 'px'; }; + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error const onKeyDown = (event) => { const isCtrlOrShiftKey = event?.detail?.ctrlKey || event?.detail?.shiftKey; diff --git a/frontend/src/pages/Project/Details/Settings/index.tsx b/frontend/src/pages/Project/Details/Settings/index.tsx index d858249ce2..a945c513da 100644 --- a/frontend/src/pages/Project/Details/Settings/index.tsx +++ b/frontend/src/pages/Project/Details/Settings/index.tsx @@ -17,7 +17,6 @@ import { SelectCSD, SpaceBetween, StatusIndicator, - Toggle, } from 'components'; import { HotspotIds } from 'layouts/AppLayout/TutorialPanel/constants'; @@ -25,13 +24,13 @@ import { useBreadcrumbs, useHelpPanel, useNotifications } from 'hooks'; import { riseRouterException } from 'libs'; import { ROUTES } from 'routes'; import { useGetProjectQuery, useUpdateProjectMembersMutation, useUpdateProjectMutation } from 'services/project'; +import { useGetUserDataQuery } from 'services/user'; import { useCheckAvailableProjectPermission } from 'pages/Project/hooks/useCheckAvailableProjectPermission'; import { useConfigProjectCliCommand } from 'pages/Project/hooks/useConfigProjectCliComand'; import { useDeleteProject } from 'pages/Project/hooks/useDeleteProject'; import { ProjectMembers } from 'pages/Project/Members'; import { getProjectRoleByUserName } from 'pages/Project/utils'; -import { useGetUserDataQuery } from 'services/user'; import { useBackendsTable } from '../../Backends/hooks'; import { BackendsTable } from '../../Backends/Table'; @@ -79,10 +78,7 @@ export const ProjectSettings: React.FC = () => { { label: t('projects.edit.visibility.public') || '', value: 'public' }, ]; - const currentVisibility = data?.isPublic ? 'public' : 'private'; - const [selectedVisibility, setSelectedVisibility] = useState( - data?.isPublic ? visibilityOptions[1] : visibilityOptions[0] - ); + const [selectedVisibility, setSelectedVisibility] = useState(data?.isPublic ? visibilityOptions[1] : visibilityOptions[0]); useEffect(() => { setSelectedVisibility(data?.isPublic ? visibilityOptions[1] : visibilityOptions[0]); @@ -123,6 +119,7 @@ export const ProjectSettings: React.FC = () => { content: t('projects.edit.update_members_success'), }); }) + // eslint-disable-next-line @typescript-eslint/no-explicit-any .catch((error: any) => { pushNotification({ type: 'error', @@ -145,6 +142,7 @@ export const ProjectSettings: React.FC = () => { content: t('projects.edit.update_visibility_success'), }); }) + // eslint-disable-next-line @typescript-eslint/no-explicit-any .catch((error: any) => { pushNotification({ type: 'error', @@ -162,6 +160,7 @@ export const ProjectSettings: React.FC = () => { deleteProject(data) .then(() => navigate(ROUTES.PROJECT.LIST)) + // eslint-disable-next-line @typescript-eslint/no-explicit-any .catch((error: any) => { console.error('Delete project failed:', error); }); @@ -286,7 +285,14 @@ export const ProjectSettings: React.FC = () => { setSelectedVisibility(event.detail.selectedOption as { label: string; value: string })} + onChange={(event) => + setSelectedVisibility( + event.detail.selectedOption as { + label: string; + value: string; + }, + ) + } expandToViewport={true} filteringType="auto" /> diff --git a/frontend/src/pages/Project/Details/index.tsx b/frontend/src/pages/Project/Details/index.tsx index 81d64f9d25..b26c921a05 100644 --- a/frontend/src/pages/Project/Details/index.tsx +++ b/frontend/src/pages/Project/Details/index.tsx @@ -1,37 +1,14 @@ -import React, { useMemo } from 'react'; -import { Outlet, useNavigate, useParams } from 'react-router-dom'; -import { useTranslation } from 'react-i18next'; +import React from 'react'; +import { Outlet, useParams } from 'react-router-dom'; -import { Button, ContentLayout, DetailsHeader } from 'components'; - -import { useAppSelector, useNotifications } from 'hooks'; -import { selectUserData } from 'App/slice'; -import { ROUTES } from 'routes'; -import { useGetProjectQuery, useAddProjectMemberMutation, useRemoveProjectMemberMutation } from 'services/project'; -import { getProjectRoleByUserName } from '../utils'; -import { useProjectMemberActions } from '../hooks/useProjectMemberActions'; +import { ContentLayout, DetailsHeader } from 'components'; export const ProjectDetails: React.FC = () => { - const { t } = useTranslation(); const params = useParams(); - const navigate = useNavigate(); const paramProjectName = params.projectName ?? ''; - const userData = useAppSelector(selectUserData); - const { handleJoinProject, handleLeaveProject, isMemberActionLoading } = useProjectMemberActions(); - - const { data: project } = useGetProjectQuery({ name: paramProjectName }); - - const currentUserRole = useMemo(() => { - if (!userData?.username || !project) return null; - return getProjectRoleByUserName(project, userData.username); - }, [project, userData?.username]); - - const isProjectOwner = userData?.username === project?.owner.username; - - const isMember = currentUserRole !== null; return ( - }> + }> ); diff --git a/frontend/src/pages/Project/Members/index.tsx b/frontend/src/pages/Project/Members/index.tsx index 33eafc0813..8009f9fb67 100644 --- a/frontend/src/pages/Project/Members/index.tsx +++ b/frontend/src/pages/Project/Members/index.tsx @@ -1,16 +1,26 @@ import React, { useEffect, useMemo, useState } from 'react'; import { useFieldArray, useForm } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; -import { useNavigate } from 'react-router-dom'; -import { Button, ButtonWithConfirmation, FormSelect, Header, Link, ListEmptyMessage, Pagination, SpaceBetween, Table } from 'components'; - -import { useAppSelector, useCollection, useNotifications } from 'hooks'; -import { selectUserData } from 'App/slice'; +import { + Button, + ButtonWithConfirmation, + FormSelect, + Header, + Link, + ListEmptyMessage, + Pagination, + SpaceBetween, + Table, +} from 'components'; + +import { useAppSelector, useCollection } from 'hooks'; import { ROUTES } from 'routes'; import { useGetUserListQuery } from 'services/user'; -import { useProjectMemberActions } from '../hooks/useProjectMemberActions'; +import { selectUserData } from 'App/slice'; + +import { useProjectMemberActions } from '../hooks/useProjectMemberActions'; import { UserAutosuggest } from './UsersAutosuggest'; import { IProps, TFormValues, TProjectMemberWithIndex } from './types'; @@ -21,8 +31,6 @@ import styles from './styles.module.scss'; export const ProjectMembers: React.FC = ({ members, loading, onChange, readonly, isAdmin, project }) => { const { t } = useTranslation(); - const navigate = useNavigate(); - const [pushNotification] = useNotifications(); const [selectedItems, setSelectedItems] = useState([]); const { data: usersData } = useGetUserListQuery(); const userData = useAppSelector(selectUserData); @@ -39,12 +47,10 @@ export const ProjectMembers: React.FC = ({ members, loading, onChange, r const currentUserRole = useMemo(() => { if (!userData?.username) return null; - const member = members?.find(m => m.user.username === userData.username); + const member = members?.find((m) => m.user.username === userData.username); return member?.project_role || null; }, [members, userData?.username]); - const isProjectOwner = userData?.username === project?.owner.username; - const isMember = currentUserRole !== null; useEffect(() => { @@ -113,14 +119,9 @@ export const ProjectMembers: React.FC = ({ members, loading, onChange, r // Add management actions only if not readonly if (!readonly) { actions.push( - + , ); } @@ -135,13 +136,13 @@ export const ProjectMembers: React.FC = ({ members, loading, onChange, r variant="normal" > {isMemberActionLoading ? t('common.loading') : t('projects.join')} - + , ); } else { // Check if user is the last admin - if so, don't show leave button - const adminCount = project.members.filter(member => member.project_role === 'admin').length; + const adminCount = project.members.filter((member) => member.project_role === 'admin').length; const isLastAdmin = currentUserRole === 'admin' && adminCount <= 1; - + if (!isLastAdmin) { // Only show leave button if user is not the last admin actions.unshift( @@ -154,17 +155,18 @@ export const ProjectMembers: React.FC = ({ members, loading, onChange, r confirmContent={t('projects.leave_confirm_message')} confirmButtonLabel={t('projects.leave')} > - {isMemberActionLoading - ? t('common.loading') - : t('projects.leave') - } - + {isMemberActionLoading ? t('common.loading') : t('projects.leave')} + , ); } } } - return actions.length > 0 ? {actions} : undefined; + return actions.length > 0 ? ( + + {actions} + + ) : undefined; }; const COLUMN_DEFINITIONS = [ @@ -218,7 +220,6 @@ export const ProjectMembers: React.FC = ({ members, loading, onChange, r ]; return ( - // eslint-disable-next-line @typescript-eslint/no-empty-function
{})}> = ({ members, loading, onChange, r columnDefinitions={COLUMN_DEFINITIONS} items={items} header={ -
+
{t('projects.edit.members.section_title')}
} diff --git a/frontend/src/pages/Project/hooks/useProjectMemberActions.ts b/frontend/src/pages/Project/hooks/useProjectMemberActions.ts index c474aedc3a..6005e313ad 100644 --- a/frontend/src/pages/Project/hooks/useProjectMemberActions.ts +++ b/frontend/src/pages/Project/hooks/useProjectMemberActions.ts @@ -1,27 +1,24 @@ -import { useNavigate } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { useNotifications } from 'hooks'; -import { ROUTES } from 'routes'; import { useAddProjectMemberMutation, useRemoveProjectMemberMutation } from 'services/project'; export const useProjectMemberActions = () => { const { t } = useTranslation(); - const navigate = useNavigate(); const [pushNotification] = useNotifications(); const [addMember, { isLoading: isAdding }] = useAddProjectMemberMutation(); const [removeMember, { isLoading: isRemoving }] = useRemoveProjectMemberMutation(); const handleJoinProject = async (projectName: string, username: string) => { if (!username || !projectName) return; - + try { await addMember({ project_name: projectName, username: username, project_role: 'user', }).unwrap(); - + pushNotification({ type: 'success', content: t('projects.join_success'), @@ -37,23 +34,24 @@ export const useProjectMemberActions = () => { const handleLeaveProject = async (projectName: string, username: string, onLeaveSuccess?: () => void) => { if (!username || !projectName) return; - + try { await removeMember({ project_name: projectName, username: username, }).unwrap(); - + pushNotification({ type: 'success', content: t('projects.leave_success'), }); - + // Optionally call the success callback onLeaveSuccess?.(); + // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { console.error('Failed to leave project:', error); - + // Extract the specific error message from the backend let errorMessage = t('projects.leave_error'); if (error?.data?.detail) { @@ -68,7 +66,7 @@ export const useProjectMemberActions = () => { errorMessage = error.data.detail.msg; } } - + pushNotification({ type: 'error', content: errorMessage, @@ -81,6 +79,6 @@ export const useProjectMemberActions = () => { return { handleJoinProject, handleLeaveProject, - isMemberActionLoading + isMemberActionLoading, }; -}; +}; diff --git a/frontend/src/pages/Runs/Details/Logs/index.tsx b/frontend/src/pages/Runs/Details/Logs/index.tsx index 61cce49eb3..aaffbf41cc 100644 --- a/frontend/src/pages/Runs/Details/Logs/index.tsx +++ b/frontend/src/pages/Runs/Details/Logs/index.tsx @@ -22,7 +22,7 @@ export const Logs: React.FC = ({ className, projectName, runName, jobSub const { t } = useTranslation(); const appliedTheme = useAppSelector(selectSystemMode); - const terminalInstance = useRef(new Terminal({scrollback: 10000000})); + const terminalInstance = useRef(new Terminal({ scrollback: 10000000 })); const fitAddonInstance = useRef(new FitAddon()); const [logsData, setLogsData] = useState([]); const [isLoading, setIsLoading] = useState(false); diff --git a/frontend/src/pages/Runs/Details/RunDetails/index.tsx b/frontend/src/pages/Runs/Details/RunDetails/index.tsx index f623fbe55b..79d2c23014 100644 --- a/frontend/src/pages/Runs/Details/RunDetails/index.tsx +++ b/frontend/src/pages/Runs/Details/RunDetails/index.tsx @@ -51,7 +51,7 @@ export const RunDetails = () => { if (!runData) return null; const status = finishedRunStatuses.includes(runData.status) - ? runData.latest_job_submission?.status ?? runData.status + ? (runData.latest_job_submission?.status ?? runData.status) : runData.status; const terminationReason = finishedRunStatuses.includes(runData.status) ? runData.latest_job_submission?.termination_reason diff --git a/frontend/src/pages/Runs/List/hooks/useColumnsDefinitions.tsx b/frontend/src/pages/Runs/List/hooks/useColumnsDefinitions.tsx index 74b6187b38..c53d9688a6 100644 --- a/frontend/src/pages/Runs/List/hooks/useColumnsDefinitions.tsx +++ b/frontend/src/pages/Runs/List/hooks/useColumnsDefinitions.tsx @@ -75,7 +75,7 @@ export const useColumnsDefinitions = () => { header: t('projects.run.status'), cell: (item: IRun) => { const status = finishedRunStatuses.includes(item.status) - ? item.latest_job_submission?.status ?? item.status + ? (item.latest_job_submission?.status ?? item.status) : item.status; const terminationReason = finishedRunStatuses.includes(item.status) ? item.latest_job_submission?.termination_reason diff --git a/frontend/src/pages/Runs/List/hooks/useEmptyMessages.tsx b/frontend/src/pages/Runs/List/hooks/useEmptyMessages.tsx index 553e197a4f..d495f03976 100644 --- a/frontend/src/pages/Runs/List/hooks/useEmptyMessages.tsx +++ b/frontend/src/pages/Runs/List/hooks/useEmptyMessages.tsx @@ -24,7 +24,9 @@ export const useEmptyMessages = ({ title={t('projects.run.empty_message_title')} message={t('projects.run.quickstart_message_text')} > - + ); } diff --git a/frontend/src/pages/User/Add/index.tsx b/frontend/src/pages/User/Add/index.tsx index 88453641f3..8f2d084d44 100644 --- a/frontend/src/pages/User/Add/index.tsx +++ b/frontend/src/pages/User/Add/index.tsx @@ -41,6 +41,7 @@ export const UserAdd: React.FC = () => { }); navigate(ROUTES.USER.DETAILS.FORMAT(data.username)); + // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (e) { pushNotification({ type: 'error', diff --git a/frontend/src/pages/User/Edit/index.tsx b/frontend/src/pages/User/Edit/index.tsx index 911b17ddc5..d11b68a64e 100644 --- a/frontend/src/pages/User/Edit/index.tsx +++ b/frontend/src/pages/User/Edit/index.tsx @@ -69,6 +69,7 @@ export const UserEdit: React.FC = () => { type: 'success', content: t('users.edit.refresh_token_success_notification'), }); + // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (e) { pushNotification({ type: 'error', @@ -94,6 +95,7 @@ export const UserEdit: React.FC = () => { }); navigate(ROUTES.USER.DETAILS.FORMAT(data.username ?? paramUserName)); + // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (e) { pushNotification({ type: 'error', diff --git a/frontend/src/router.tsx b/frontend/src/router.tsx index 59f215d28d..5dfaa9fb4e 100644 --- a/frontend/src/router.tsx +++ b/frontend/src/router.tsx @@ -6,8 +6,8 @@ import { Navigate } from 'react-router-dom'; import App from 'App'; import { LoginByEntraIDCallback } from 'App/Login/EntraID/LoginByEntraIDCallback'; import { LoginByGithubCallback } from 'App/Login/LoginByGithubCallback'; -import { LoginByOktaCallback } from 'App/Login/LoginByOktaCallback'; import { LoginByGoogleCallback } from 'App/Login/LoginByGoogleCallback'; +import { LoginByOktaCallback } from 'App/Login/LoginByOktaCallback'; import { TokenLogin } from 'App/Login/TokenLogin'; import { Logout } from 'App/Logout'; import { FleetDetails, FleetList } from 'pages/Fleets'; diff --git a/frontend/src/services/project.ts b/frontend/src/services/project.ts index 064aac024d..9e05e444ac 100644 --- a/frontend/src/services/project.ts +++ b/frontend/src/services/project.ts @@ -5,6 +5,7 @@ import { base64ToArrayBuffer } from 'libs'; import fetchBaseQueryHeaders from 'libs/fetchBaseQueryHeaders'; // Helper function to transform backend response to frontend format +// eslint-disable-next-line @typescript-eslint/no-explicit-any const transformProjectResponse = (project: any): IProject => ({ ...project, isPublic: project.is_public, @@ -28,8 +29,8 @@ export const projectApi = createApi({ }; }, - transformResponse: (response: any[]): IProject[] => - response.map(transformProjectResponse), + // eslint-disable-next-line @typescript-eslint/no-explicit-any + transformResponse: (response: any[]): IProject[] => response.map(transformProjectResponse), providesTags: (result) => result diff --git a/frontend/src/services/run.ts b/frontend/src/services/run.ts index 0e88185979..3dc00ac10e 100644 --- a/frontend/src/services/run.ts +++ b/frontend/src/services/run.ts @@ -108,6 +108,7 @@ export const runApi = createApi({ try { await queryFulfilled; + // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (e) { patchGetRunResult.undo(); patchGetAllRunResult.undo(); diff --git a/frontend/tests/__mocks__/svgrMock.ts b/frontend/tests/__mocks__/svgrMock.ts index 461ea547bd..4b5a5e5dff 100644 --- a/frontend/tests/__mocks__/svgrMock.ts +++ b/frontend/tests/__mocks__/svgrMock.ts @@ -1,3 +1,2 @@ -// eslint-disable-next-line export default 'SvgrURL'; export const ReactComponent = 'IconMock'; diff --git a/frontend/webpack/dev.js b/frontend/webpack/dev.js index 33ff767ed6..a286e77f4c 100644 --- a/frontend/webpack/dev.js +++ b/frontend/webpack/dev.js @@ -1,13 +1,13 @@ -const webpack = require("webpack"); -const {join} = require('path'); -const {srcDir} = require('./env'); +const webpack = require('webpack'); +const { join } = require('path'); +const { srcDir } = require('./env'); const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); -const CircularDependencyPlugin = require('circular-dependency-plugin') +const CircularDependencyPlugin = require('circular-dependency-plugin'); const port = 3000; module.exports = { - mode: "development", + mode: 'development', entry: [ `webpack-dev-server/client?http://localhost:${port}`, // bundle the client for webpack-dev-server and connect to the provided endpoint join(srcDir, 'index.tsx'), // the entry point of our App @@ -18,27 +18,27 @@ module.exports = { hot: true, // enable HMR on the server historyApiFallback: true, // fixes error 404-ish errors when using react router :see this SO question: https://stackoverflow.com/questions/43209666/react-router-v4-cannot-get-url headers: { - "Access-Control-Allow-Origin": "*", - "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS", - "Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization" + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS', + 'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization', }, proxy: [ { - context: ["/api"], + context: ['/api'], changeOrigin: true, target: 'http://127.0.0.1:8000', logLevel: 'debug', - } + }, ], client: { overlay: { runtimeErrors: (error) => { - return !error.message.includes("ResizeObserver loop completed with undelivered notifications"); + return !error.message.includes('ResizeObserver loop completed with undelivered notifications'); }, }, - } + }, }, - devtool: "cheap-module-source-map", + devtool: 'cheap-module-source-map', plugins: [ new webpack.HotModuleReplacementPlugin(), // enable HMR globally new ReactRefreshWebpackPlugin(), @@ -55,6 +55,6 @@ module.exports = { allowAsyncCycles: false, // set the current working directory for displaying module paths cwd: process.cwd(), - }) + }), ], };