From 506e273dda50b54c6eca414f0fb41e747b57b16b Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Tue, 3 Jun 2025 12:51:15 +0300 Subject: [PATCH 01/29] Fixed pre-commit eslint configuration --- .pre-commit-config.yaml | 20 +- frontend/.eslintignore | 12 - frontend/.eslintrc | 34 - frontend/eslint-precommit.config.mjs | 23 + frontend/eslint.config.mjs | 75 ++ frontend/package-lock.json | 849 ++++++++++-------- frontend/package.json | 16 +- .../FileUploader/FileEntry/index.tsx | 2 +- frontend/src/components/Tabs/index.tsx | 2 +- .../src/components/form/Checkbox/index.tsx | 2 +- .../src/components/form/CodeEditor/index.tsx | 2 +- frontend/src/components/form/Input/index.tsx | 4 +- .../src/components/form/Multiselect/index.tsx | 2 +- .../components/form/RadioButtons/index.tsx | 2 +- .../form/S3BucketSelector/index.tsx | 2 +- frontend/src/components/form/Select/index.tsx | 2 +- .../src/components/form/Textarea/index.tsx | 2 +- frontend/src/components/form/Tiles/index.tsx | 2 +- .../layouts/AppLayout/TutorialPanel/hooks.ts | 1 - frontend/src/libs/index.ts | 14 +- frontend/src/pages/Models/Details/index.tsx | 6 +- .../Project/Backends/Table/constants.tsx | 35 +- .../Project/Backends/YAMLForm/constants.tsx | 5 +- .../Project/Details/Settings/constants.tsx | 11 +- .../Project/Gateways/Table/constants.tsx | 8 +- frontend/src/pages/Project/Members/index.tsx | 1 - frontend/src/pages/User/Add/index.tsx | 1 + frontend/src/pages/User/Edit/index.tsx | 2 + frontend/src/services/run.ts | 1 + frontend/tests/__mocks__/svgrMock.ts | 1 - 30 files changed, 671 insertions(+), 468 deletions(-) delete mode 100644 frontend/.eslintignore delete mode 100644 frontend/.eslintrc create mode 100644 frontend/eslint-precommit.config.mjs create mode 100644 frontend/eslint.config.mjs diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6ba9d9b410..4424de3143 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,19 +19,15 @@ repos: - id: end-of-file-fixer - repo: https://github.com/pre-commit/mirrors-eslint - rev: '' + rev: 'v9.28.0' hooks: - id: eslint - name: ESLint - entry: eslint --fix --config frontend/.eslintrc --ignore-path frontend/.eslintignore - language: node - pass_filenames: false - cwd: "frontend/" + args: ['--fix', '--config', 'frontend/eslint-precommit.config.mjs', '--no-warn-ignored', 'frontend/'] additional_dependencies: - - eslint@8.31.0 - - eslint-config-prettier@8.10.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 - - '@typescript-eslint/eslint-plugin@5.48.1' - - '@typescript-eslint/parser@5.48.1' + - eslint-plugin-prettier@5.4.1 + - eslint-plugin-simple-import-sort@12.1.1 + - '@typescript-eslint/eslint-plugin@8.33.1' + - '@typescript-eslint/parser@8.33.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/eslint-precommit.config.mjs b/frontend/eslint-precommit.config.mjs new file mode 100644 index 0000000000..d80c98d536 --- /dev/null +++ b/frontend/eslint-precommit.config.mjs @@ -0,0 +1,23 @@ +import { defineConfig, globalIgnores } from 'eslint/config'; + +import { BASE_CONFIG } from './eslint.config.mjs'; + +export default defineConfig([ + globalIgnores([ + 'frontend/node_modules', + 'frontend/build', + 'frontend/server.js', + 'frontend/src/locale', + 'frontend/src/types', + 'frontend/src/setupProxy.js', + 'frontend/webpack/**/*', + 'frontend/webpack/env.js', + 'frontend/webpack/prod.js', + 'frontend/public', + 'frontend/staticServer.js', + 'frontend/webpack.config.js', + 'docs/**/*', + ]), + + { ...BASE_CONFIG }, +]); diff --git a/frontend/eslint.config.mjs b/frontend/eslint.config.mjs new file mode 100644 index 0000000000..83836c5693 --- /dev/null +++ b/frontend/eslint.config.mjs @@ -0,0 +1,75 @@ +import { defineConfig, globalIgnores } from 'eslint/config'; +import i18N from 'eslint-plugin-i18n'; +import simpleImportSort from 'eslint-plugin-simple-import-sort'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { FlatCompat } from '@eslint/eslintrc'; +import js from '@eslint/js'; +import typescriptEslint from '@typescript-eslint/eslint-plugin'; +import tsParser from '@typescript-eslint/parser'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all, +}); + +export 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$'], + ], + }, + ], + }, +}; + +export default 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 1380434841..51d828f53f 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "dstackai", "version": "2.0.0", - "license": "MIT", + "license": "Apache 2.0", "dependencies": { "@cloudscape-design/chat-components": "^1.0.19", "@cloudscape-design/collection-hooks": "^1.0.56", @@ -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,11 +79,11 @@ "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", @@ -96,7 +98,7 @@ "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 +2554,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 +2581,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 +2637,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 +2648,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 +2664,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 +2685,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 +2697,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 +2796,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 +2847,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 +4110,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 +4251,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 +5126,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 +5206,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 +5366,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 +5434,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 +5731,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" } @@ -7394,10 +7530,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", @@ -8114,18 +8251,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", @@ -8578,69 +8703,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 +8789,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 +8869,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 +8904,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 +8921,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 +9293,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 +9518,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", @@ -10873,15 +11004,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 +12221,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 +12269,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" } @@ -12618,12 +12742,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", @@ -19677,15 +19795,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" @@ -20768,22 +20887,6 @@ "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", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/rst-selector-parser": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz", @@ -21953,6 +22056,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 +22298,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 +22419,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..c21d7e1e93 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -27,6 +27,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 +47,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,11 +57,11 @@ "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", @@ -74,7 +76,7 @@ "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", 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 2cdf5e5ebf..07f46f1aed 100644 --- a/frontend/src/layouts/AppLayout/TutorialPanel/hooks.ts +++ b/frontend/src/layouts/AppLayout/TutorialPanel/hooks.ts @@ -64,7 +64,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/index.ts b/frontend/src/libs/index.ts index 50a163db06..7573d19a89 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/pages/Models/Details/index.tsx b/frontend/src/pages/Models/Details/index.tsx index 26fbc4b177..d21536e4aa 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/Backends/Table/constants.tsx b/frontend/src/pages/Project/Backends/Table/constants.tsx index ac23a6881c..0d9fb99128 100644 --- a/frontend/src/pages/Project/Backends/Table/constants.tsx +++ b/frontend/src/pages/Project/Backends/Table/constants.tsx @@ -4,13 +4,26 @@ export const BACKENDS_HELP_SKY = { header:

Backends

, body: ( <> -

To use dstack with cloud providers, you have to configure backends.

+

+ To use dstack with cloud providers, you have to configure backends. +

Marketplace

-

By default, dstack Sky includes a preset of backends that let you access compute from the {' '} - dstack marketplace and pay through your dstack Sky user billing.

+

+ By default, dstack Sky includes a preset of backends that let you access compute from the{' '} + dstack marketplace and pay through your dstack Sky user billing. +

Your own cloud accounts

-

You can also configure custom backends to use your own cloud providers, either instead of or in addition to the default ones.

-

See the documentation for the list of supported backends.

+

+ You can also configure custom backends to use your own cloud providers, either instead of or in addition to the + default ones. +

+

+ See the{' '} + + documentation + {' '} + for the list of supported backends. +

), }; @@ -19,8 +32,16 @@ export const BACKENDS_HELP_ENTERPRISE = { header:

Backends

, body: ( <> -

To use dstack with cloud providers, you have to configure backends.

-

See the documentation for the list of supported backends.

+

+ To use dstack with cloud providers, you have to configure backends. +

+

+ See the{' '} + + documentation + {' '} + for the list of supported backends. +

), }; diff --git a/frontend/src/pages/Project/Backends/YAMLForm/constants.tsx b/frontend/src/pages/Project/Backends/YAMLForm/constants.tsx index 9d47cfc830..a139f137d5 100644 --- a/frontend/src/pages/Project/Backends/YAMLForm/constants.tsx +++ b/frontend/src/pages/Project/Backends/YAMLForm/constants.tsx @@ -68,7 +68,10 @@ export const CONFIG_YAML_HELP_ENTERPRISE = {

Each backend type may support different properties. See the{' '} - documentaiton for more examples. + + documentaiton + {' '} + for more examples.

), diff --git a/frontend/src/pages/Project/Details/Settings/constants.tsx b/frontend/src/pages/Project/Details/Settings/constants.tsx index 8963724323..4b3acefce4 100644 --- a/frontend/src/pages/Project/Details/Settings/constants.tsx +++ b/frontend/src/pages/Project/Details/Settings/constants.tsx @@ -6,12 +6,17 @@ export const CLI_INFO = { <>

To use this project with your CLI, add it using the - - dstack project add command. + + dstack project add + {' '} + command.

To learn how to install the CLI, refer to the{' '} - installation guide. + + installation + {' '} + guide.

), diff --git a/frontend/src/pages/Project/Gateways/Table/constants.tsx b/frontend/src/pages/Project/Gateways/Table/constants.tsx index 9b03b807b8..53ec3b15ae 100644 --- a/frontend/src/pages/Project/Gateways/Table/constants.tsx +++ b/frontend/src/pages/Project/Gateways/Table/constants.tsx @@ -5,7 +5,13 @@ export const GATEWAYS_INFO = { body: ( <>

Gateways manage the ingress traffic for running services.

-

To learn more about gateways, see the documentation.

+

+ To learn more about gateways, see the{' '} + + documentation + + . +

), }; diff --git a/frontend/src/pages/Project/Members/index.tsx b/frontend/src/pages/Project/Members/index.tsx index b728d1962f..753d8e382a 100644 --- a/frontend/src/pages/Project/Members/index.tsx +++ b/frontend/src/pages/Project/Members/index.tsx @@ -141,7 +141,6 @@ export const ProjectMembers: React.FC = ({ members, loading, onChange, r ]; return ( - // eslint-disable-next-line @typescript-eslint/no-empty-function
{})}> { }); 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/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'; From 3c50a5e889e0ddbd5c315e8a373ab30f2300eca2 Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Tue, 3 Jun 2025 12:56:37 +0300 Subject: [PATCH 02/29] Fixed pre-commit eslint configuration --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4424de3143..74b6fe6204 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,7 +22,7 @@ repos: rev: 'v9.28.0' hooks: - id: eslint - args: ['--fix', '--config', 'frontend/eslint-precommit.config.mjs', '--no-warn-ignored', 'frontend/'] + args: ['--fix', '--config', './frontend/eslint-precommit.config.mjs', '--no-warn-ignored', './frontend/'] additional_dependencies: - eslint@9.28.0 - eslint-config-prettier@10.1.5 From a3ede8dbc6ee71d4a7a0a8f10f7be3f9b9bc81fa Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Tue, 3 Jun 2025 13:00:51 +0300 Subject: [PATCH 03/29] Fixed pre-commit eslint configuration --- .pre-commit-config.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 74b6fe6204..b5a1dac72a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,12 +22,14 @@ repos: rev: 'v9.28.0' hooks: - id: eslint - args: ['--fix', '--config', './frontend/eslint-precommit.config.mjs', '--no-warn-ignored', './frontend/'] + args: ['--fix', '--config', 'frontend/eslint-precommit.config.mjs', '--no-warn-ignored', 'frontend/'] additional_dependencies: - eslint@9.28.0 - eslint-config-prettier@10.1.5 - eslint-plugin-i18n@2.4.0 - eslint-plugin-prettier@5.4.1 - eslint-plugin-simple-import-sort@12.1.1 + - '@eslint/eslintrc@3.3.1' + - '@eslint/js@9.28.0' - '@typescript-eslint/eslint-plugin@8.33.1' - '@typescript-eslint/parser@8.33.1' From 95a48157360b2bbdbe9981336ca25d96aa228384 Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Tue, 3 Jun 2025 13:41:50 +0300 Subject: [PATCH 04/29] Fixed pre-commit eslint configuration --- .pre-commit-config.yaml | 4 +++- ...config.mjs => eslint-precommit.config.cjs} | 9 +++---- .../{eslint.config.mjs => eslint.config.cjs} | 24 ++++++++----------- 3 files changed, 16 insertions(+), 21 deletions(-) rename frontend/{eslint-precommit.config.mjs => eslint-precommit.config.cjs} (73%) rename frontend/{eslint.config.mjs => eslint.config.cjs} (71%) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b5a1dac72a..6ceb5822c6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,7 +22,9 @@ repos: rev: 'v9.28.0' hooks: - id: eslint - args: ['--fix', '--config', 'frontend/eslint-precommit.config.mjs', '--no-warn-ignored', 'frontend/'] + args: ['--fix', '--config', 'frontend/eslint-precommit.config.cjs', '--no-warn-ignored', 'frontend/'] + language: node + files: ^frontend/.*\.(js|jsx|ts|tsx)$ additional_dependencies: - eslint@9.28.0 - eslint-config-prettier@10.1.5 diff --git a/frontend/eslint-precommit.config.mjs b/frontend/eslint-precommit.config.cjs similarity index 73% rename from frontend/eslint-precommit.config.mjs rename to frontend/eslint-precommit.config.cjs index d80c98d536..48638fb780 100644 --- a/frontend/eslint-precommit.config.mjs +++ b/frontend/eslint-precommit.config.cjs @@ -1,8 +1,7 @@ -import { defineConfig, globalIgnores } from 'eslint/config'; +const { defineConfig, globalIgnores } = require('eslint/config'); +const { BASE_CONFIG } = require('./eslint.config.cjs'); -import { BASE_CONFIG } from './eslint.config.mjs'; - -export default defineConfig([ +module.exports = defineConfig([ globalIgnores([ 'frontend/node_modules', 'frontend/build', @@ -16,8 +15,6 @@ export default defineConfig([ 'frontend/public', 'frontend/staticServer.js', 'frontend/webpack.config.js', - 'docs/**/*', ]), - { ...BASE_CONFIG }, ]); diff --git a/frontend/eslint.config.mjs b/frontend/eslint.config.cjs similarity index 71% rename from frontend/eslint.config.mjs rename to frontend/eslint.config.cjs index 83836c5693..3cfe1c41e4 100644 --- a/frontend/eslint.config.mjs +++ b/frontend/eslint.config.cjs @@ -1,28 +1,24 @@ -import { defineConfig, globalIgnores } from 'eslint/config'; -import i18N from 'eslint-plugin-i18n'; -import simpleImportSort from 'eslint-plugin-simple-import-sort'; -import path from 'node:path'; -import { fileURLToPath } from 'node:url'; -import { FlatCompat } from '@eslint/eslintrc'; -import js from '@eslint/js'; -import typescriptEslint from '@typescript-eslint/eslint-plugin'; -import tsParser from '@typescript-eslint/parser'; +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 __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); const compat = new FlatCompat({ baseDirectory: __dirname, recommendedConfig: js.configs.recommended, allConfig: js.configs.all, }); -export const BASE_CONFIG = { +const BASE_CONFIG = { extends: compat.extends( 'eslint:recommended', 'plugin:@typescript-eslint/eslint-recommended', 'plugin:@typescript-eslint/recommended', 'prettier', - 'plugin:prettier/recommended', + 'plugin:prettier/recommended' ), plugins: { @@ -56,7 +52,7 @@ export const BASE_CONFIG = { }, }; -export default defineConfig([ +module.exports = defineConfig([ globalIgnores([ 'node_modules', 'build', From f9b3b33b79d1ac8832153c19499684a86524dedb Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Tue, 3 Jun 2025 17:07:26 +0300 Subject: [PATCH 05/29] Fixed pre-commit eslint configuration --- .pre-commit-config.yaml | 3 +-- frontend/src/pages/Fleets/Details/index.tsx | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6ceb5822c6..2694c42881 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,8 +22,7 @@ repos: rev: 'v9.28.0' hooks: - id: eslint - args: ['--fix', '--config', 'frontend/eslint-precommit.config.cjs', '--no-warn-ignored', 'frontend/'] - language: node + args: ['--fix', '--config', 'frontend/eslint-precommit.config.cjs', 'frontend/'] files: ^frontend/.*\.(js|jsx|ts|tsx)$ additional_dependencies: - eslint@9.28.0 diff --git a/frontend/src/pages/Fleets/Details/index.tsx b/frontend/src/pages/Fleets/Details/index.tsx index 658d61c010..05c40f51e1 100644 --- a/frontend/src/pages/Fleets/Details/index.tsx +++ b/frontend/src/pages/Fleets/Details/index.tsx @@ -34,7 +34,9 @@ export const FleetDetails: React.FC = () => { const { deleteFleets, isDeleting } = useDeleteFleet(); const { data, isLoading } = useGetFleetDetailsQuery( + { + projectName: paramProjectName, fleetId: paramFleetId, }, From 5621c472f0132146dbca020fcc8fe2799eba0070 Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Wed, 4 Jun 2025 13:50:53 +0300 Subject: [PATCH 06/29] Fixed pre-commit eslint configuration --- frontend/src/pages/Fleets/Details/index.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/frontend/src/pages/Fleets/Details/index.tsx b/frontend/src/pages/Fleets/Details/index.tsx index 05c40f51e1..658d61c010 100644 --- a/frontend/src/pages/Fleets/Details/index.tsx +++ b/frontend/src/pages/Fleets/Details/index.tsx @@ -34,9 +34,7 @@ export const FleetDetails: React.FC = () => { const { deleteFleets, isDeleting } = useDeleteFleet(); const { data, isLoading } = useGetFleetDetailsQuery( - { - projectName: paramProjectName, fleetId: paramFleetId, }, From eba4ddb0ddf60b2093c72f313bfda8ce4a080513 Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Tue, 1 Jul 2025 22:00:17 +0300 Subject: [PATCH 07/29] Test commit --- frontend/src/pages/Fleets/Details/index.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/frontend/src/pages/Fleets/Details/index.tsx b/frontend/src/pages/Fleets/Details/index.tsx index e487f7a2c9..dab781792c 100644 --- a/frontend/src/pages/Fleets/Details/index.tsx +++ b/frontend/src/pages/Fleets/Details/index.tsx @@ -35,8 +35,10 @@ export const FleetDetails: React.FC = () => { const { data, isLoading } = useGetFleetDetailsQuery( { - projectName: paramProjectName, - fleetId: paramFleetId, + projectName: + paramProjectName, + fleetId: + paramFleetId, }, { refetchOnMountOrArgChange: true, From 60b9b9781b041f5d0aac4915e7ae6c8b97ccbdfa Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Tue, 1 Jul 2025 22:54:49 +0300 Subject: [PATCH 08/29] test --- .pre-commit-config.yaml | 17 ----------------- frontend/.husky/pre-commit | 1 + 2 files changed, 1 insertion(+), 17 deletions(-) create mode 100644 frontend/.husky/pre-commit diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2694c42881..d9e8408e2c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,20 +17,3 @@ repos: rev: v5.0.0 hooks: - id: end-of-file-fixer - - - repo: https://github.com/pre-commit/mirrors-eslint - rev: 'v9.28.0' - hooks: - - id: eslint - args: ['--fix', '--config', 'frontend/eslint-precommit.config.cjs', 'frontend/'] - files: ^frontend/.*\.(js|jsx|ts|tsx)$ - additional_dependencies: - - eslint@9.28.0 - - eslint-config-prettier@10.1.5 - - eslint-plugin-i18n@2.4.0 - - eslint-plugin-prettier@5.4.1 - - eslint-plugin-simple-import-sort@12.1.1 - - '@eslint/eslintrc@3.3.1' - - '@eslint/js@9.28.0' - - '@typescript-eslint/eslint-plugin@8.33.1' - - '@typescript-eslint/parser@8.33.1' diff --git a/frontend/.husky/pre-commit b/frontend/.husky/pre-commit new file mode 100644 index 0000000000..72c4429bc9 --- /dev/null +++ b/frontend/.husky/pre-commit @@ -0,0 +1 @@ +npm test From 3bd58a3b9fa32a2cb2fa4b97e776eb48553bc00a Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Tue, 1 Jul 2025 23:08:05 +0300 Subject: [PATCH 09/29] test --- frontend/.husky/pre-commit | 5 +- frontend/package-lock.json | 624 +++++++++++++++++++- frontend/package.json | 11 +- frontend/src/pages/Fleets/Details/index.tsx | 8 +- frontend/webpack/dev.js | 33 +- 5 files changed, 657 insertions(+), 24 deletions(-) diff --git a/frontend/.husky/pre-commit b/frontend/.husky/pre-commit index 72c4429bc9..c9faf4f773 100644 --- a/frontend/.husky/pre-commit +++ b/frontend/.husky/pre-commit @@ -1 +1,4 @@ -npm test +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +npm run eslint-fix diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 51d828f53f..55242f45f0 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -89,9 +89,11 @@ "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", @@ -7130,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", @@ -7991,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" }, @@ -8462,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", @@ -9854,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", @@ -10463,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", @@ -12338,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", @@ -12426,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", @@ -12623,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", @@ -12714,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", @@ -18521,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", @@ -20859,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", @@ -20887,6 +21445,13 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, "node_modules/rst-selector-parser": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz", @@ -21544,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", @@ -21676,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", diff --git a/frontend/package.json b/frontend/package.json index c21d7e1e93..b80a88be75 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -15,7 +15,8 @@ "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": "husky" }, "devDependencies": { "@babel/cli": "^7.25.9", @@ -67,9 +68,11 @@ "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", @@ -123,5 +126,11 @@ "react-string-replace": "^1.1.1", "redux": "^5.0.1", "yup": "^0.32.11" + }, + "lint-staged": { + "*.{js,jsx,ts,tsx,vue}": [ + "eslint --fix", + "git add" + ] } } diff --git a/frontend/src/pages/Fleets/Details/index.tsx b/frontend/src/pages/Fleets/Details/index.tsx index dab781792c..207bc20914 100644 --- a/frontend/src/pages/Fleets/Details/index.tsx +++ b/frontend/src/pages/Fleets/Details/index.tsx @@ -35,10 +35,10 @@ export const FleetDetails: React.FC = () => { const { data, isLoading } = useGetFleetDetailsQuery( { - projectName: - paramProjectName, - fleetId: - paramFleetId, + projectName: + paramProjectName, + fleetId: + paramFleetId, }, { refetchOnMountOrArgChange: true, diff --git a/frontend/webpack/dev.js b/frontend/webpack/dev.js index 33ff767ed6..31a864e40a 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,30 @@ 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', + // target: 'http://127.0.0.1:8000', + target: 'https://sky.dstack.ai/', //0ab1c6ee-3f7b-4839-a259-5e5c6074a97f + // target: 'https://sky-stage.dstack.ai/', //29001ee8-897c-47ea-bfec-819f56835ffe + // target: 'https://cloud.dstack.ai/', //0ab1c6ee-3f7b-4839-a259-5e5c6074a97f 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 +58,6 @@ module.exports = { allowAsyncCycles: false, // set the current working directory for displaying module paths cwd: process.cwd(), - }) + }), ], }; From b4cce7e356978b24e33c1018f6972400ab3f2507 Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Tue, 1 Jul 2025 23:10:59 +0300 Subject: [PATCH 10/29] test --- .../src/App/Login/EnterpriseLogin/index.tsx | 4 +- frontend/src/libs/filters.ts | 35 ++++++------ frontend/src/libs/run.ts | 3 +- frontend/src/pages/Fleets/Details/index.tsx | 12 ++--- .../pages/Project/Details/Settings/index.tsx | 15 ++++-- frontend/src/pages/Project/Details/index.tsx | 14 ++--- frontend/src/pages/Project/Members/index.tsx | 53 ++++++++++--------- .../Project/hooks/useProjectMemberActions.ts | 20 +++---- .../src/pages/Runs/Details/Logs/index.tsx | 2 +- .../pages/Runs/Details/RunDetails/index.tsx | 2 +- .../Runs/List/hooks/useColumnsDefinitions.tsx | 2 +- .../Runs/List/hooks/useEmptyMessages.tsx | 4 +- frontend/src/router.tsx | 2 +- frontend/src/services/project.ts | 3 +- 14 files changed, 93 insertions(+), 78 deletions(-) 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/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/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/Fleets/Details/index.tsx b/frontend/src/pages/Fleets/Details/index.tsx index 207bc20914..5e40b58d86 100644 --- a/frontend/src/pages/Fleets/Details/index.tsx +++ b/frontend/src/pages/Fleets/Details/index.tsx @@ -34,12 +34,12 @@ export const FleetDetails: React.FC = () => { const { deleteFleets, isDeleting } = useDeleteFleet(); const { data, isLoading } = useGetFleetDetailsQuery( - { - projectName: - paramProjectName, - fleetId: - paramFleetId, - }, + { + projectName: + paramProjectName, + fleetId: + paramFleetId, + }, { refetchOnMountOrArgChange: true, }, diff --git a/frontend/src/pages/Project/Details/Settings/index.tsx b/frontend/src/pages/Project/Details/Settings/index.tsx index d858249ce2..d14f0d966b 100644 --- a/frontend/src/pages/Project/Details/Settings/index.tsx +++ b/frontend/src/pages/Project/Details/Settings/index.tsx @@ -25,13 +25,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'; @@ -80,9 +80,7 @@ export const ProjectSettings: React.FC = () => { ]; 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]); @@ -286,7 +284,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..5eadee7e66 100644 --- a/frontend/src/pages/Project/Details/index.tsx +++ b/frontend/src/pages/Project/Details/index.tsx @@ -1,15 +1,17 @@ import React, { useMemo } from 'react'; -import { Outlet, useNavigate, useParams } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; +import { Outlet, useNavigate, 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 { useAddProjectMemberMutation, useGetProjectQuery, useRemoveProjectMemberMutation } from 'services/project'; + +import { selectUserData } from 'App/slice'; + import { useProjectMemberActions } from '../hooks/useProjectMemberActions'; +import { getProjectRoleByUserName } from '../utils'; export const ProjectDetails: React.FC = () => { const { t } = useTranslation(); @@ -18,7 +20,7 @@ export const ProjectDetails: React.FC = () => { const paramProjectName = params.projectName ?? ''; const userData = useAppSelector(selectUserData); const { handleJoinProject, handleLeaveProject, isMemberActionLoading } = useProjectMemberActions(); - + const { data: project } = useGetProjectQuery({ name: paramProjectName }); const currentUserRole = useMemo(() => { @@ -31,7 +33,7 @@ export const ProjectDetails: React.FC = () => { const isMember = currentUserRole !== null; return ( - }> + }> ); diff --git a/frontend/src/pages/Project/Members/index.tsx b/frontend/src/pages/Project/Members/index.tsx index b48a5764d4..c7604d4ce4 100644 --- a/frontend/src/pages/Project/Members/index.tsx +++ b/frontend/src/pages/Project/Members/index.tsx @@ -3,14 +3,25 @@ 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 { + Button, + ButtonWithConfirmation, + FormSelect, + Header, + Link, + ListEmptyMessage, + Pagination, + SpaceBetween, + Table, +} from 'components'; import { useAppSelector, useCollection, useNotifications } from 'hooks'; -import { selectUserData } from 'App/slice'; 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'; @@ -39,7 +50,7 @@ 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]); @@ -113,14 +124,9 @@ export const ProjectMembers: React.FC = ({ members, loading, onChange, r // Add management actions only if not readonly if (!readonly) { actions.push( - + , ); } @@ -135,13 +141,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 +160,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 = [ @@ -226,11 +233,7 @@ export const ProjectMembers: React.FC = ({ 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..1b5c622677 100644 --- a/frontend/src/pages/Project/hooks/useProjectMemberActions.ts +++ b/frontend/src/pages/Project/hooks/useProjectMemberActions.ts @@ -1,5 +1,5 @@ -import { useNavigate } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; +import { useNavigate } from 'react-router-dom'; import { useNotifications } from 'hooks'; import { ROUTES } from 'routes'; @@ -14,14 +14,14 @@ export const useProjectMemberActions = () => { 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 +37,23 @@ 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?.(); } 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 +68,7 @@ export const useProjectMemberActions = () => { errorMessage = error.data.detail.msg; } } - + pushNotification({ type: 'error', content: errorMessage, @@ -81,6 +81,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/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..952908b21c 100644 --- a/frontend/src/services/project.ts +++ b/frontend/src/services/project.ts @@ -28,8 +28,7 @@ export const projectApi = createApi({ }; }, - transformResponse: (response: any[]): IProject[] => - response.map(transformProjectResponse), + transformResponse: (response: any[]): IProject[] => response.map(transformProjectResponse), providesTags: (result) => result From 359f2fd28d22eb8aec98df163a020f70de9c59d7 Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Tue, 1 Jul 2025 23:20:31 +0300 Subject: [PATCH 11/29] Test commit --- frontend/package.json | 2 +- frontend/src/pages/Fleets/Details/index.tsx | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index b80a88be75..8d748b4701 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -12,7 +12,7 @@ "build": "cross-env NODE_ENV=production webpack build --config webpack.config.js", "build-sky": "cross-env NODE_ENV=production UI_VERSION=sky webpack build --config webpack.config.js", "eslint": "eslint ./src --ext .js,.jsx,.ts,.tsx", - "eslint-fix": "eslint ./src --ext .js,.jsx,.ts,.tsx --fix", + "eslint-fix": "eslint ./src --ext .js,.jsx,.ts,.tsx --fix --max-warnings=0", "test": "jest", "test:update-snapshots": "jest -u", "generate-api": "npx @rtk-query/codegen-openapi openapi-config.ts", diff --git a/frontend/src/pages/Fleets/Details/index.tsx b/frontend/src/pages/Fleets/Details/index.tsx index 5e40b58d86..dab781792c 100644 --- a/frontend/src/pages/Fleets/Details/index.tsx +++ b/frontend/src/pages/Fleets/Details/index.tsx @@ -34,12 +34,12 @@ export const FleetDetails: React.FC = () => { const { deleteFleets, isDeleting } = useDeleteFleet(); const { data, isLoading } = useGetFleetDetailsQuery( - { - projectName: - paramProjectName, - fleetId: - paramFleetId, - }, + { + projectName: + paramProjectName, + fleetId: + paramFleetId, + }, { refetchOnMountOrArgChange: true, }, From 0ada141aec22a5178c1f943245ed807e8f630de4 Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Tue, 1 Jul 2025 23:23:24 +0300 Subject: [PATCH 12/29] Test commit --- frontend/.husky/pre-commit | 2 +- frontend/package.json | 2 +- frontend/src/pages/Fleets/Details/index.tsx | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/.husky/pre-commit b/frontend/.husky/pre-commit index c9faf4f773..d24fdfc601 100644 --- a/frontend/.husky/pre-commit +++ b/frontend/.husky/pre-commit @@ -1,4 +1,4 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" -npm run eslint-fix +npx lint-staged diff --git a/frontend/package.json b/frontend/package.json index 8d748b4701..2a9b9b4b87 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -128,7 +128,7 @@ "yup": "^0.32.11" }, "lint-staged": { - "*.{js,jsx,ts,tsx,vue}": [ + "*.{js,jsx,ts,tsx}": [ "eslint --fix", "git add" ] diff --git a/frontend/src/pages/Fleets/Details/index.tsx b/frontend/src/pages/Fleets/Details/index.tsx index dab781792c..207bc20914 100644 --- a/frontend/src/pages/Fleets/Details/index.tsx +++ b/frontend/src/pages/Fleets/Details/index.tsx @@ -35,10 +35,10 @@ export const FleetDetails: React.FC = () => { const { data, isLoading } = useGetFleetDetailsQuery( { - projectName: - paramProjectName, - fleetId: - paramFleetId, + projectName: + paramProjectName, + fleetId: + paramFleetId, }, { refetchOnMountOrArgChange: true, From ccd6d150921681dd72e1eb3bd213fbf9b7dc8d67 Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Tue, 1 Jul 2025 23:24:44 +0300 Subject: [PATCH 13/29] Test commit --- frontend/package.json | 2 +- frontend/src/pages/Fleets/Details/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 2a9b9b4b87..e5fcc8f6d3 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -129,7 +129,7 @@ }, "lint-staged": { "*.{js,jsx,ts,tsx}": [ - "eslint --fix", + "eslint --fix --max-warnings=0", "git add" ] } diff --git a/frontend/src/pages/Fleets/Details/index.tsx b/frontend/src/pages/Fleets/Details/index.tsx index 207bc20914..bd1cf2570c 100644 --- a/frontend/src/pages/Fleets/Details/index.tsx +++ b/frontend/src/pages/Fleets/Details/index.tsx @@ -36,7 +36,7 @@ export const FleetDetails: React.FC = () => { const { data, isLoading } = useGetFleetDetailsQuery( { projectName: - paramProjectName, + paramProjectName, fleetId: paramFleetId, }, From 2aeab47ec3add89711335ba9f427a6e323b2d48f Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Tue, 1 Jul 2025 23:36:06 +0300 Subject: [PATCH 14/29] Test commit --- frontend/package.json | 5 +++-- frontend/src/pages/Fleets/Details/index.tsx | 7 +++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index e5fcc8f6d3..8aea06e156 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -16,7 +16,8 @@ "test": "jest", "test:update-snapshots": "jest -u", "generate-api": "npx @rtk-query/codegen-openapi openapi-config.ts", - "prepare": "husky" + "prepare": "husky", + "precommit": "lint-staged" }, "devDependencies": { "@babel/cli": "^7.25.9", @@ -129,7 +130,7 @@ }, "lint-staged": { "*.{js,jsx,ts,tsx}": [ - "eslint --fix --max-warnings=0", + "eslint --fix", "git add" ] } diff --git a/frontend/src/pages/Fleets/Details/index.tsx b/frontend/src/pages/Fleets/Details/index.tsx index bd1cf2570c..86b513d61c 100644 --- a/frontend/src/pages/Fleets/Details/index.tsx +++ b/frontend/src/pages/Fleets/Details/index.tsx @@ -35,10 +35,9 @@ export const FleetDetails: React.FC = () => { const { data, isLoading } = useGetFleetDetailsQuery( { - projectName: - paramProjectName, - fleetId: - paramFleetId, + projectName: paramProjectName, + fleetId: + paramFleetId, }, { refetchOnMountOrArgChange: true, From 4a04a3964512cac0100861d060e989ef45dc3707 Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Tue, 1 Jul 2025 23:44:10 +0300 Subject: [PATCH 15/29] Test commit --- frontend/lint-staged.config.cjs | 3 +++ frontend/package.json | 2 +- frontend/src/pages/Fleets/Details/index.tsx | 6 +++++- 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 frontend/lint-staged.config.cjs diff --git a/frontend/lint-staged.config.cjs b/frontend/lint-staged.config.cjs new file mode 100644 index 0000000000..faa50bfa1f --- /dev/null +++ b/frontend/lint-staged.config.cjs @@ -0,0 +1,3 @@ +module.exports = { + '*.{ts,tsx}': ['eslint --fix', 'git add'], +}; diff --git a/frontend/package.json b/frontend/package.json index 8aea06e156..fb8c6bfa2f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -129,7 +129,7 @@ "yup": "^0.32.11" }, "lint-staged": { - "*.{js,jsx,ts,tsx}": [ + "*.{ts,tsx}": [ "eslint --fix", "git add" ] diff --git a/frontend/src/pages/Fleets/Details/index.tsx b/frontend/src/pages/Fleets/Details/index.tsx index 86b513d61c..7815cbedcd 100644 --- a/frontend/src/pages/Fleets/Details/index.tsx +++ b/frontend/src/pages/Fleets/Details/index.tsx @@ -35,8 +35,12 @@ export const FleetDetails: React.FC = () => { const { data, isLoading } = useGetFleetDetailsQuery( { - projectName: paramProjectName, + projectName: + + paramProjectName, fleetId: + + paramFleetId, }, { From 6228f39d0ef3efc1737e67dcde3dd1405204b4b3 Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Tue, 1 Jul 2025 23:44:57 +0300 Subject: [PATCH 16/29] Test commit --- frontend/.husky/pre-commit | 2 +- frontend/package.json | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/frontend/.husky/pre-commit b/frontend/.husky/pre-commit index d24fdfc601..3e1cef8843 100644 --- a/frontend/.husky/pre-commit +++ b/frontend/.husky/pre-commit @@ -1,4 +1,4 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" -npx lint-staged +npm run precommit diff --git a/frontend/package.json b/frontend/package.json index fb8c6bfa2f..911fbc9664 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -128,10 +128,4 @@ "redux": "^5.0.1", "yup": "^0.32.11" }, - "lint-staged": { - "*.{ts,tsx}": [ - "eslint --fix", - "git add" - ] - } } From fb1269b2538134e4aa730d66837b2d1cfb14bce8 Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Tue, 1 Jul 2025 23:45:17 +0300 Subject: [PATCH 17/29] Test commit --- frontend/src/pages/Fleets/Details/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/pages/Fleets/Details/index.tsx b/frontend/src/pages/Fleets/Details/index.tsx index 7815cbedcd..986b2b6aa4 100644 --- a/frontend/src/pages/Fleets/Details/index.tsx +++ b/frontend/src/pages/Fleets/Details/index.tsx @@ -37,11 +37,11 @@ export const FleetDetails: React.FC = () => { { projectName: - paramProjectName, + paramProjectName, fleetId: - paramFleetId, + paramFleetId, }, { refetchOnMountOrArgChange: true, From 37df0b1a32379e3cdf41c4e7306e8cccd9da52cc Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Tue, 1 Jul 2025 23:47:09 +0300 Subject: [PATCH 18/29] Test commit --- frontend/package.json | 6 ++++++ frontend/src/pages/Fleets/Details/index.tsx | 9 ++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 911fbc9664..8aea06e156 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -128,4 +128,10 @@ "redux": "^5.0.1", "yup": "^0.32.11" }, + "lint-staged": { + "*.{js,jsx,ts,tsx}": [ + "eslint --fix", + "git add" + ] + } } diff --git a/frontend/src/pages/Fleets/Details/index.tsx b/frontend/src/pages/Fleets/Details/index.tsx index 986b2b6aa4..e487f7a2c9 100644 --- a/frontend/src/pages/Fleets/Details/index.tsx +++ b/frontend/src/pages/Fleets/Details/index.tsx @@ -35,13 +35,8 @@ export const FleetDetails: React.FC = () => { const { data, isLoading } = useGetFleetDetailsQuery( { - projectName: - - paramProjectName, - fleetId: - - - paramFleetId, + projectName: paramProjectName, + fleetId: paramFleetId, }, { refetchOnMountOrArgChange: true, From 8575878487ccf73b2611ee5aa872a84d30fa88b5 Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Tue, 1 Jul 2025 23:47:25 +0300 Subject: [PATCH 19/29] Test commit --- frontend/src/pages/Fleets/Details/index.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/frontend/src/pages/Fleets/Details/index.tsx b/frontend/src/pages/Fleets/Details/index.tsx index e487f7a2c9..48db5c5db1 100644 --- a/frontend/src/pages/Fleets/Details/index.tsx +++ b/frontend/src/pages/Fleets/Details/index.tsx @@ -35,8 +35,13 @@ export const FleetDetails: React.FC = () => { const { data, isLoading } = useGetFleetDetailsQuery( { - projectName: paramProjectName, - fleetId: paramFleetId, + projectName: + + paramProjectName, + + fleetId: + +paramFleetId, }, { refetchOnMountOrArgChange: true, From 867093a424969b834a8a337af7789e8dfb7ea31d Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Tue, 1 Jul 2025 23:47:48 +0300 Subject: [PATCH 20/29] Test commit --- frontend/src/pages/Fleets/Details/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/pages/Fleets/Details/index.tsx b/frontend/src/pages/Fleets/Details/index.tsx index 48db5c5db1..c10f4b84b1 100644 --- a/frontend/src/pages/Fleets/Details/index.tsx +++ b/frontend/src/pages/Fleets/Details/index.tsx @@ -39,6 +39,7 @@ export const FleetDetails: React.FC = () => { paramProjectName, + fleetId: paramFleetId, From 01d5733a419eb304d0fa375be8832b2d5296846e Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Tue, 1 Jul 2025 23:59:44 +0300 Subject: [PATCH 21/29] Test commit --- frontend/lint-staged.config.cjs | 3 --- frontend/src/pages/Fleets/Details/index.tsx | 5 ++--- 2 files changed, 2 insertions(+), 6 deletions(-) delete mode 100644 frontend/lint-staged.config.cjs diff --git a/frontend/lint-staged.config.cjs b/frontend/lint-staged.config.cjs deleted file mode 100644 index faa50bfa1f..0000000000 --- a/frontend/lint-staged.config.cjs +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - '*.{ts,tsx}': ['eslint --fix', 'git add'], -}; diff --git a/frontend/src/pages/Fleets/Details/index.tsx b/frontend/src/pages/Fleets/Details/index.tsx index c10f4b84b1..8a100af6e4 100644 --- a/frontend/src/pages/Fleets/Details/index.tsx +++ b/frontend/src/pages/Fleets/Details/index.tsx @@ -37,12 +37,11 @@ export const FleetDetails: React.FC = () => { { projectName: - paramProjectName, - fleetId: +paramProjectName, -paramFleetId, +fleetId: paramFleetId, }, { refetchOnMountOrArgChange: true, From 62a2c271a299146647fa461fb956d37befd78b18 Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Wed, 2 Jul 2025 00:03:32 +0300 Subject: [PATCH 22/29] Test commit --- frontend/.husky/pre-commit | 1 + frontend/package.json | 2 +- frontend/src/pages/Fleets/Details/index.tsx | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/.husky/pre-commit b/frontend/.husky/pre-commit index 3e1cef8843..103c436e26 100644 --- a/frontend/.husky/pre-commit +++ b/frontend/.husky/pre-commit @@ -1,4 +1,5 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" +cd frontend npm run precommit diff --git a/frontend/package.json b/frontend/package.json index 8aea06e156..d25eef0a70 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -16,7 +16,7 @@ "test": "jest", "test:update-snapshots": "jest -u", "generate-api": "npx @rtk-query/codegen-openapi openapi-config.ts", - "prepare": "husky", + "prepare": "cd .. && husky frontend/.husky", "precommit": "lint-staged" }, "devDependencies": { diff --git a/frontend/src/pages/Fleets/Details/index.tsx b/frontend/src/pages/Fleets/Details/index.tsx index 8a100af6e4..e70d46e839 100644 --- a/frontend/src/pages/Fleets/Details/index.tsx +++ b/frontend/src/pages/Fleets/Details/index.tsx @@ -38,7 +38,6 @@ export const FleetDetails: React.FC = () => { projectName: - paramProjectName, fleetId: paramFleetId, From 6f71cd0b2c058feac4b54ddccd2e3b87f6580d85 Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Wed, 2 Jul 2025 00:05:49 +0300 Subject: [PATCH 23/29] Test commit --- frontend/src/pages/Fleets/Details/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/pages/Fleets/Details/index.tsx b/frontend/src/pages/Fleets/Details/index.tsx index e70d46e839..bde276e994 100644 --- a/frontend/src/pages/Fleets/Details/index.tsx +++ b/frontend/src/pages/Fleets/Details/index.tsx @@ -37,7 +37,6 @@ export const FleetDetails: React.FC = () => { { projectName: - paramProjectName, fleetId: paramFleetId, From a576e92475de3b9f3d17f52947439db0154018c2 Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Wed, 2 Jul 2025 00:06:53 +0300 Subject: [PATCH 24/29] Test commit --- frontend/.husky/pre-commit | 2 ++ frontend/src/pages/Fleets/Details/index.tsx | 1 + 2 files changed, 3 insertions(+) diff --git a/frontend/.husky/pre-commit b/frontend/.husky/pre-commit index 103c436e26..b1866bd288 100644 --- a/frontend/.husky/pre-commit +++ b/frontend/.husky/pre-commit @@ -3,3 +3,5 @@ cd frontend npm run precommit + +exit 1 diff --git a/frontend/src/pages/Fleets/Details/index.tsx b/frontend/src/pages/Fleets/Details/index.tsx index bde276e994..8b55a56151 100644 --- a/frontend/src/pages/Fleets/Details/index.tsx +++ b/frontend/src/pages/Fleets/Details/index.tsx @@ -40,6 +40,7 @@ export const FleetDetails: React.FC = () => { paramProjectName, fleetId: paramFleetId, + }, { refetchOnMountOrArgChange: true, From 7931bd38211c73b33d8952f7f807263bd4bbb629 Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Wed, 2 Jul 2025 16:03:59 +0300 Subject: [PATCH 25/29] test --- frontend/src/pages/Fleets/Details/index.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/frontend/src/pages/Fleets/Details/index.tsx b/frontend/src/pages/Fleets/Details/index.tsx index 8b55a56151..f06d054f05 100644 --- a/frontend/src/pages/Fleets/Details/index.tsx +++ b/frontend/src/pages/Fleets/Details/index.tsx @@ -35,12 +35,9 @@ export const FleetDetails: React.FC = () => { const { data, isLoading } = useGetFleetDetailsQuery( { - projectName: - -paramProjectName, - -fleetId: paramFleetId, + projectName: paramProjectName, + fleetId: paramFleetId, }, { refetchOnMountOrArgChange: true, From 10a0bbf6a71102f6fcdf978200e2b99a92ab11dc Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Wed, 2 Jul 2025 16:04:24 +0300 Subject: [PATCH 26/29] test --- frontend/.husky/pre-commit | 5 ----- frontend/src/pages/Fleets/Details/index.tsx | 1 - 2 files changed, 6 deletions(-) diff --git a/frontend/.husky/pre-commit b/frontend/.husky/pre-commit index b1866bd288..c72b09fe63 100644 --- a/frontend/.husky/pre-commit +++ b/frontend/.husky/pre-commit @@ -1,7 +1,2 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" - cd frontend npm run precommit - -exit 1 diff --git a/frontend/src/pages/Fleets/Details/index.tsx b/frontend/src/pages/Fleets/Details/index.tsx index f06d054f05..e487f7a2c9 100644 --- a/frontend/src/pages/Fleets/Details/index.tsx +++ b/frontend/src/pages/Fleets/Details/index.tsx @@ -36,7 +36,6 @@ export const FleetDetails: React.FC = () => { const { data, isLoading } = useGetFleetDetailsQuery( { projectName: paramProjectName, - fleetId: paramFleetId, }, { From e07674feeed8cc61f8fef823533d14c98d1ec0c6 Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Wed, 2 Jul 2025 16:13:58 +0300 Subject: [PATCH 27/29] [Feature]: Update git hooks and package json #2705 --- frontend/package.json | 4 +-- .../pages/Project/Details/Settings/index.tsx | 5 +-- frontend/src/pages/Project/Details/index.tsx | 31 ++----------------- frontend/src/pages/Project/Members/index.tsx | 7 +---- .../Project/hooks/useProjectMemberActions.ts | 4 +-- frontend/src/services/project.ts | 2 ++ 6 files changed, 12 insertions(+), 41 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index d25eef0a70..3bbbd115b9 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -12,7 +12,7 @@ "build": "cross-env NODE_ENV=production webpack build --config webpack.config.js", "build-sky": "cross-env NODE_ENV=production UI_VERSION=sky webpack build --config webpack.config.js", "eslint": "eslint ./src --ext .js,.jsx,.ts,.tsx", - "eslint-fix": "eslint ./src --ext .js,.jsx,.ts,.tsx --fix --max-warnings=0", + "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", @@ -130,7 +130,7 @@ }, "lint-staged": { "*.{js,jsx,ts,tsx}": [ - "eslint --fix", + "eslint --fix --max-warnings=0", "git add" ] } diff --git a/frontend/src/pages/Project/Details/Settings/index.tsx b/frontend/src/pages/Project/Details/Settings/index.tsx index d14f0d966b..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'; @@ -79,7 +78,6 @@ 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]); useEffect(() => { @@ -121,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', @@ -143,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', @@ -160,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); }); diff --git a/frontend/src/pages/Project/Details/index.tsx b/frontend/src/pages/Project/Details/index.tsx index 5eadee7e66..b26c921a05 100644 --- a/frontend/src/pages/Project/Details/index.tsx +++ b/frontend/src/pages/Project/Details/index.tsx @@ -1,36 +1,11 @@ -import React, { useMemo } from 'react'; -import { useTranslation } from 'react-i18next'; -import { Outlet, useNavigate, useParams } from 'react-router-dom'; +import React from 'react'; +import { Outlet, useParams } from 'react-router-dom'; -import { Button, ContentLayout, DetailsHeader } from 'components'; - -import { useAppSelector, useNotifications } from 'hooks'; -import { ROUTES } from 'routes'; -import { useAddProjectMemberMutation, useGetProjectQuery, useRemoveProjectMemberMutation } from 'services/project'; - -import { selectUserData } from 'App/slice'; - -import { useProjectMemberActions } from '../hooks/useProjectMemberActions'; -import { getProjectRoleByUserName } from '../utils'; +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 c7604d4ce4..8009f9fb67 100644 --- a/frontend/src/pages/Project/Members/index.tsx +++ b/frontend/src/pages/Project/Members/index.tsx @@ -1,7 +1,6 @@ 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, @@ -15,7 +14,7 @@ import { Table, } from 'components'; -import { useAppSelector, useCollection, useNotifications } from 'hooks'; +import { useAppSelector, useCollection } from 'hooks'; import { ROUTES } from 'routes'; import { useGetUserListQuery } from 'services/user'; @@ -32,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); @@ -54,8 +51,6 @@ export const ProjectMembers: React.FC = ({ members, loading, onChange, r return member?.project_role || null; }, [members, userData?.username]); - const isProjectOwner = userData?.username === project?.owner.username; - const isMember = currentUserRole !== null; useEffect(() => { diff --git a/frontend/src/pages/Project/hooks/useProjectMemberActions.ts b/frontend/src/pages/Project/hooks/useProjectMemberActions.ts index 1b5c622677..6005e313ad 100644 --- a/frontend/src/pages/Project/hooks/useProjectMemberActions.ts +++ b/frontend/src/pages/Project/hooks/useProjectMemberActions.ts @@ -1,13 +1,10 @@ import { useTranslation } from 'react-i18next'; -import { useNavigate } from 'react-router-dom'; 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(); @@ -51,6 +48,7 @@ export const useProjectMemberActions = () => { // 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); diff --git a/frontend/src/services/project.ts b/frontend/src/services/project.ts index 952908b21c..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,6 +29,7 @@ export const projectApi = createApi({ }; }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any transformResponse: (response: any[]): IProject[] => response.map(transformProjectResponse), providesTags: (result) => From 372eb128534a0d1b77f089870a801c725238c727 Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Wed, 2 Jul 2025 16:21:13 +0300 Subject: [PATCH 28/29] [Feature]: Update git hooks and package json #2705 --- frontend/eslint-precommit.config.cjs | 20 -------------------- frontend/package.json | 2 +- frontend/webpack/dev.js | 16 ++++++++-------- 3 files changed, 9 insertions(+), 29 deletions(-) delete mode 100644 frontend/eslint-precommit.config.cjs diff --git a/frontend/eslint-precommit.config.cjs b/frontend/eslint-precommit.config.cjs deleted file mode 100644 index 48638fb780..0000000000 --- a/frontend/eslint-precommit.config.cjs +++ /dev/null @@ -1,20 +0,0 @@ -const { defineConfig, globalIgnores } = require('eslint/config'); -const { BASE_CONFIG } = require('./eslint.config.cjs'); - -module.exports = defineConfig([ - globalIgnores([ - 'frontend/node_modules', - 'frontend/build', - 'frontend/server.js', - 'frontend/src/locale', - 'frontend/src/types', - 'frontend/src/setupProxy.js', - 'frontend/webpack/**/*', - 'frontend/webpack/env.js', - 'frontend/webpack/prod.js', - 'frontend/public', - 'frontend/staticServer.js', - 'frontend/webpack.config.js', - ]), - { ...BASE_CONFIG }, -]); diff --git a/frontend/package.json b/frontend/package.json index 3bbbd115b9..f4de75c603 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -130,7 +130,7 @@ }, "lint-staged": { "*.{js,jsx,ts,tsx}": [ - "eslint --fix --max-warnings=0", + "eslint --fix --max-warnings=0 --no-warn-ignored", "git add" ] } diff --git a/frontend/webpack/dev.js b/frontend/webpack/dev.js index 31a864e40a..805d34d8d4 100644 --- a/frontend/webpack/dev.js +++ b/frontend/webpack/dev.js @@ -10,7 +10,7 @@ module.exports = { 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 + join(srcDir, 'index.tsx') // the entry point of our App ], devServer: { port, @@ -20,7 +20,7 @@ module.exports = { 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-Headers': 'X-Requested-With, content-type, Authorization' }, proxy: [ { @@ -30,16 +30,16 @@ module.exports = { target: 'https://sky.dstack.ai/', //0ab1c6ee-3f7b-4839-a259-5e5c6074a97f // target: 'https://sky-stage.dstack.ai/', //29001ee8-897c-47ea-bfec-819f56835ffe // target: 'https://cloud.dstack.ai/', //0ab1c6ee-3f7b-4839-a259-5e5c6074a97f - logLevel: 'debug', - }, + logLevel: 'debug' + } ], client: { overlay: { runtimeErrors: (error) => { return !error.message.includes('ResizeObserver loop completed with undelivered notifications'); - }, - }, - }, + } + } + } }, devtool: 'cheap-module-source-map', plugins: [ @@ -57,7 +57,7 @@ module.exports = { // e.g. via import(/* webpackMode: "weak" */ './file.js') allowAsyncCycles: false, // set the current working directory for displaying module paths - cwd: process.cwd(), + cwd: process.cwd() }), ], }; From 86369ea1e10bed214bfebc76fee7dbd88eed05a6 Mon Sep 17 00:00:00 2001 From: Oleg Vavilov Date: Thu, 3 Jul 2025 17:46:57 +0300 Subject: [PATCH 29/29] [Feature]: Update git hooks and package json #2705 --- frontend/webpack/dev.js | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/frontend/webpack/dev.js b/frontend/webpack/dev.js index 805d34d8d4..a286e77f4c 100644 --- a/frontend/webpack/dev.js +++ b/frontend/webpack/dev.js @@ -10,7 +10,7 @@ module.exports = { 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 + join(srcDir, 'index.tsx'), // the entry point of our App ], devServer: { port, @@ -20,26 +20,23 @@ module.exports = { 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-Headers': 'X-Requested-With, content-type, Authorization', }, proxy: [ { context: ['/api'], changeOrigin: true, - // target: 'http://127.0.0.1:8000', - target: 'https://sky.dstack.ai/', //0ab1c6ee-3f7b-4839-a259-5e5c6074a97f - // target: 'https://sky-stage.dstack.ai/', //29001ee8-897c-47ea-bfec-819f56835ffe - // target: 'https://cloud.dstack.ai/', //0ab1c6ee-3f7b-4839-a259-5e5c6074a97f - logLevel: 'debug' - } + target: 'http://127.0.0.1:8000', + logLevel: 'debug', + }, ], client: { overlay: { runtimeErrors: (error) => { return !error.message.includes('ResizeObserver loop completed with undelivered notifications'); - } - } - } + }, + }, + }, }, devtool: 'cheap-module-source-map', plugins: [ @@ -57,7 +54,7 @@ module.exports = { // e.g. via import(/* webpackMode: "weak" */ './file.js') allowAsyncCycles: false, // set the current working directory for displaying module paths - cwd: process.cwd() + cwd: process.cwd(), }), ], };