diff --git a/.eslintrc.json b/.eslintrc.json index 0f4a73c3..c616a36d 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -18,7 +18,7 @@ ], "parser": "@typescript-eslint/parser", "ignorePatterns": ["resources/group_snippet.js"], - "plugins": ["import"], + "plugins": ["import", "unused-imports"], "settings": { "import/resolver": { "typescript": {} diff --git a/package-lock.json b/package-lock.json index 0d8dee56..c259efef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,15 +44,16 @@ "@types/node-forge": "^1.3.11", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", - "@typescript-eslint/eslint-plugin": "^5.0.0", - "@typescript-eslint/parser": "^5.0.0", + "@typescript-eslint/eslint-plugin": "^7.16.1", + "@typescript-eslint/parser": "^7.16.1", "electron": "30.0.8", - "eslint": "^8.0.1", + "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-import": "^2.29.1", "eslint-plugin-react": "^7.34.2", "eslint-plugin-react-hooks": "^4.6.2", + "eslint-plugin-unused-imports": "^3.2.0", "husky": "^9.0.11", "lint-staged": "^15.2.5", "ts-node": "^10.0.0", @@ -1373,17 +1374,19 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", "dev": true, - "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, - "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -1404,8 +1407,9 @@ }, "node_modules/@eslint/js": { "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, - "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -1447,8 +1451,10 @@ }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", "dev": true, - "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^2.0.2", "debug": "^4.3.1", @@ -1472,8 +1478,10 @@ }, "node_modules/@humanwhocodes/object-schema": { "version": "2.0.3", - "dev": true, - "license": "BSD-3-Clause" + "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/@jest/schemas": { "version": "29.6.3", @@ -3233,11 +3241,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "dev": true, - "license": "MIT" - }, "node_modules/@types/json5": { "version": "0.0.29", "dev": true, @@ -3321,11 +3324,6 @@ "@types/node": "*" } }, - "node_modules/@types/semver": { - "version": "7.5.8", - "dev": true, - "license": "MIT" - }, "node_modules/@types/yauzl": { "version": "2.10.3", "license": "MIT", @@ -3335,31 +3333,31 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.62.0", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", + "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==", "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": "7.16.1", + "@typescript-eslint/type-utils": "7.16.1", + "@typescript-eslint/utils": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.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" + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -3368,24 +3366,26 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.62.0", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.1.tgz", + "integrity": "sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==", "dev": true, - "license": "BSD-2-Clause", "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": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "debug": "^4.3.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -3394,15 +3394,16 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", + "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", "dev": true, - "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -3410,24 +3411,25 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.62.0", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz", + "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==", "dev": true, - "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/utils": "7.16.1", "debug": "^4.3.4", - "tsutils": "^3.21.0" + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "*" + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -3436,11 +3438,12 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.62.0", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", "dev": true, - "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -3448,20 +3451,22 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", + "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -3473,61 +3478,54 @@ } } }, - "node_modules/@typescript-eslint/utils": { - "version": "5.62.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": "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" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=16 || 14 >=14.17" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { - "version": "5.1.1", + "node_modules/@typescript-eslint/utils": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", + "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1" }, "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/estraverse": { - "version": "4.3.0", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", "dev": true, - "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" + "@typescript-eslint/types": "7.16.1", + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -3536,8 +3534,9 @@ }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true }, "node_modules/@vitejs/plugin-react": { "version": "4.3.1", @@ -3679,9 +3678,10 @@ } }, "node_modules/acorn": { - "version": "8.11.3", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "dev": true, - "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -3691,8 +3691,9 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", + "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" } @@ -3740,8 +3741,9 @@ }, "node_modules/ajv": { "version": "6.12.6", + "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", @@ -3837,8 +3839,9 @@ }, "node_modules/argparse": { "version": "2.0.1", - "dev": true, - "license": "Python-2.0" + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "node_modules/aria-hidden": { "version": "1.2.4", @@ -5767,8 +5770,9 @@ }, "node_modules/eslint": { "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -6008,10 +6012,41 @@ "semver": "bin/semver.js" } }, + "node_modules/eslint-plugin-unused-imports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-3.2.0.tgz", + "integrity": "sha512-6uXyn6xdINEpxE1MtDjxQsyXB37lfyO2yKGVVgtD7WEWQGORSOZjgrD6hBhvGv4/SO+TOlS+UnC6JppRqbuwGQ==", + "dev": true, + "dependencies": { + "eslint-rule-composer": "^0.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "6 - 7", + "eslint": "8" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + } + } + }, + "node_modules/eslint-rule-composer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz", + "integrity": "sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, "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==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -6036,8 +6071,9 @@ }, "node_modules/eslint/node_modules/doctrine": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, - "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -6058,8 +6094,9 @@ }, "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==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -6313,8 +6350,9 @@ }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true }, "node_modules/fast-fifo": { "version": "1.3.2", @@ -6348,8 +6386,9 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -6373,8 +6412,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" }, @@ -6469,8 +6509,9 @@ }, "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==", "dev": true, - "license": "MIT", "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", @@ -6482,8 +6523,9 @@ }, "node_modules/flatted": { "version": "3.3.1", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true }, "node_modules/flora-colossus": { "version": "2.0.0", @@ -6891,8 +6933,9 @@ }, "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, - "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -7731,8 +7774,9 @@ }, "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, - "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -7767,8 +7811,9 @@ }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "dev": true, - "license": "MIT" + "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/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -8753,11 +8798,6 @@ "dev": true, "license": "MIT" }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "dev": true, - "license": "MIT" - }, "node_modules/negotiator": { "version": "0.6.3", "dev": true, @@ -9678,8 +9718,9 @@ }, "node_modules/punycode": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -10848,8 +10889,9 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" }, @@ -11125,6 +11167,18 @@ "node": ">=0.10.0" } }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, "node_modules/ts-node": { "version": "10.9.2", "dev": true, @@ -11201,25 +11255,6 @@ "version": "2.6.2", "license": "0BSD" }, - "node_modules/tsutils": { - "version": "3.21.0", - "dev": true, - "license": "MIT", - "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", - "dev": true, - "license": "0BSD" - }, "node_modules/type-check": { "version": "0.4.0", "dev": true, @@ -11242,8 +11277,9 @@ }, "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==", "dev": true, - "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -11446,8 +11482,9 @@ }, "node_modules/uri-js": { "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } diff --git a/package.json b/package.json index 5dd4c28f..b0985257 100644 --- a/package.json +++ b/package.json @@ -30,15 +30,16 @@ "@types/node-forge": "^1.3.11", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", - "@typescript-eslint/eslint-plugin": "^5.0.0", - "@typescript-eslint/parser": "^5.0.0", + "@typescript-eslint/eslint-plugin": "^7.16.1", + "@typescript-eslint/parser": "^7.16.1", "electron": "30.0.8", - "eslint": "^8.0.1", + "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-import": "^2.29.1", "eslint-plugin-react": "^7.34.2", "eslint-plugin-react-hooks": "^4.6.2", + "eslint-plugin-unused-imports": "^3.2.0", "husky": "^9.0.11", "lint-staged": "^15.2.5", "ts-node": "^10.0.0", diff --git a/src/components/Layout/PageHeading.tsx b/src/components/Layout/PageHeading.tsx index eac01c8b..d34ea442 100644 --- a/src/components/Layout/PageHeading.tsx +++ b/src/components/Layout/PageHeading.tsx @@ -1,5 +1,5 @@ import { HomeIcon } from '@radix-ui/react-icons' -import { Flex, Heading, IconButton, Separator } from '@radix-ui/themes' +import { Flex, Heading, IconButton } from '@radix-ui/themes' import { useNavigate } from 'react-router-dom' import { ThemeSwitcher } from '../ThemeSwitcher' @@ -14,7 +14,15 @@ export function PageHeading({ return ( <> - + { navigate('/') @@ -24,15 +32,13 @@ export function PageHeading({ - {text} + {text} - + {children} - - ) } diff --git a/src/hooks/useGeneratorStore/selectors.ts b/src/hooks/useGeneratorStore/selectors.ts index 06a308b2..70109fa3 100644 --- a/src/hooks/useGeneratorStore/selectors.ts +++ b/src/hooks/useGeneratorStore/selectors.ts @@ -16,3 +16,7 @@ export function useSelectedRule() { return rule }) } + +export function useHasRecording() { + return useGeneratorStore((state) => state.requests.length > 0) +} diff --git a/src/hooks/useGeneratorStore/useGeneratorStore.ts b/src/hooks/useGeneratorStore/useGeneratorStore.ts index e4d43162..a51ddb2f 100644 --- a/src/hooks/useGeneratorStore/useGeneratorStore.ts +++ b/src/hooks/useGeneratorStore/useGeneratorStore.ts @@ -14,7 +14,7 @@ export const useGeneratorStore = create()( ...createRulesSlice(set, get, store), ...createVariablesSlice(set, get, store), ...createThinkTimeSlice(set, get, store), - name: `generator_${Date()}`, + name: generateNewName(), setName: (name: string) => set((state) => { state.name = name @@ -30,6 +30,7 @@ export const useGeneratorStore = create()( resetRecording: () => set((state) => { state.requests = [] + state.recordingPath = '' state.filteredRequests = [] state.allowList = [] }), @@ -58,3 +59,12 @@ export const useGeneratorStore = create()( }), })) ) + +function generateNewName() { + const formatter = new Intl.DateTimeFormat('en-US', { + dateStyle: 'short', + timeStyle: 'short', + }) + const formattedDate = formatter.format(new Date()) + return `Generator ${formattedDate}` +} diff --git a/src/hooks/useSetWindowTitle.ts b/src/hooks/useSetWindowTitle.ts new file mode 100644 index 00000000..894b523f --- /dev/null +++ b/src/hooks/useSetWindowTitle.ts @@ -0,0 +1,13 @@ +import { useEffect } from 'react' + +const defaultTitle = 'k6 studio' + +export function useSetWindowTitle(title: string) { + useEffect(() => { + document.title = `${defaultTitle} - ${title}` + + return () => { + document.title = defaultTitle + } + }, [title]) +} diff --git a/src/preload.ts b/src/preload.ts index b87251db..832e4ea2 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -3,7 +3,7 @@ import { ipcRenderer, contextBridge, IpcRendererEvent } from 'electron' import { ProxyData, K6Log } from './types' -import { HarFile, HarWithOptionalResponse } from './types/har' +import { HarFile } from './types/har' // Create listener and return clean up function to be used in useEffect function createListener(channel: string, callback: (data: T) => void) { diff --git a/src/rules/utils.ts b/src/rules/utils.ts index 7291ce27..36e0b8e7 100644 --- a/src/rules/utils.ts +++ b/src/rules/utils.ts @@ -1,5 +1,5 @@ -import { Filter, TestRule } from '@/types/rules' -import { Request, RequestSnippetSchema } from '@/types' +import { TestRule } from '@/types/rules' +import { RequestSnippetSchema } from '@/types' import { exhaustive } from '@/utils/typescript' /** diff --git a/src/utils/typescript.ts b/src/utils/typescript.ts index 5eb31506..b1998a63 100644 --- a/src/utils/typescript.ts +++ b/src/utils/typescript.ts @@ -3,7 +3,9 @@ import { StateCreator } from 'zustand' /** * Used to give a type error when not every possibility has been checked in e.g. a switch-statement. */ +// eslint-disable-next-line @typescript-eslint/no-unused-vars export function exhaustive(value: never, defaultValue?: R): R { + // eslint-disable-next-line @typescript-eslint/no-explicit-any return defaultValue ?? (value as any as R) } diff --git a/src/views/Generator/AllowList/AllowList.tsx b/src/views/Generator/AllowList/AllowList.tsx index 51afdaf2..f3373a80 100644 --- a/src/views/Generator/AllowList/AllowList.tsx +++ b/src/views/Generator/AllowList/AllowList.tsx @@ -29,12 +29,11 @@ export function AllowList() { return ( <> - + {requests.length > 0 && ( + + )} {/* Radix does not unmount dialog on close, this is need to clear local state */} {showAllowListDialog && ( 0 + const rules = useGeneratorStore((store) => store.rules) + const name = useGeneratorStore((store) => store.name) + const resetRecording = useGeneratorStore((store) => store.resetRecording) + const filteredRequests = useGeneratorStore((store) => store.filteredRequests) + const hasRecording = useHasRecording() + useSetWindowTitle(name) useEffect(() => { return () => { @@ -28,15 +26,6 @@ export function Generator() { } }, [resetRecording]) - const handleImport = async () => { - const harFile = await window.studio.har.openFile() - if (!harFile) return - - const proxyData = harToProxyData(harFile.content) - setRecording(proxyData) - setRecordingPath(harFile.path) - } - const handleExport = async () => { const script = await exportScript(filteredRequests, rules) @@ -46,12 +35,10 @@ export function Generator() { return ( <> - - + - + {hasRecording && } + {hasRecording && } @@ -64,7 +51,7 @@ export function Generator() { - + diff --git a/src/views/Generator/GeneratorSidebar/GeneratorSidebar.tsx b/src/views/Generator/GeneratorSidebar/GeneratorSidebar.tsx index bdcc3c18..05ab739b 100644 --- a/src/views/Generator/GeneratorSidebar/GeneratorSidebar.tsx +++ b/src/views/Generator/GeneratorSidebar/GeneratorSidebar.tsx @@ -3,13 +3,14 @@ import { ProxyData } from '@/types' import { Box, Flex, ScrollArea, Tabs } from '@radix-ui/themes' import { ScriptPreview } from './ScriptPreview' import { groupProxyData } from '@/utils/groups' +import { useHasRecording } from '@/hooks/useGeneratorStore' interface GeneratorSidebarProps { requests: ProxyData[] } export function GeneratorSidebar({ requests }: GeneratorSidebarProps) { - const hasRecording = requests.length > 0 + const hasRecording = useHasRecording() const groupedProxyData = groupProxyData(requests) return ( @@ -21,9 +22,11 @@ export function GeneratorSidebar({ requests }: GeneratorSidebarProps) { }} > - Requests + + Requests ({requests.length}) + - Script + Script preview store.recordingPath) + const setRecording = useGeneratorStore((store) => store.setRecording) + const setRecordingPath = useGeneratorStore((store) => store.setRecordingPath) + + const fileName = recordingPath?.split('/').pop() + + const handleImport = async () => { + const harFile = await window.studio.har.openFile() + if (!harFile) return + + const proxyData = harToProxyData(harFile.content) + setRecording(proxyData) + setRecordingPath(harFile.path) + } + + return ( + + {fileName || 'Select recording'} + + + + + + + + + You don{"'"}t have saved recordings + + + + + + + + + + + + + ) +} diff --git a/src/views/Generator/TestRuleContainer/TestRule/TestRuleActions.tsx b/src/views/Generator/TestRuleContainer/TestRule/TestRuleActions.tsx index e5586c39..3b0d8d43 100644 --- a/src/views/Generator/TestRuleContainer/TestRule/TestRuleActions.tsx +++ b/src/views/Generator/TestRuleContainer/TestRule/TestRuleActions.tsx @@ -45,7 +45,7 @@ export function TestRuleActions({ ruleId }: TestRuleActionsProps) { - Clone + Duplicate Delete diff --git a/src/views/Recorder/Recorder.tsx b/src/views/Recorder/Recorder.tsx index 93f77bb9..bfe289af 100644 --- a/src/views/Recorder/Recorder.tsx +++ b/src/views/Recorder/Recorder.tsx @@ -9,12 +9,14 @@ import { useListenProxyData } from '@/hooks/useListenProxyData' import { PageHeading } from '@/components/Layout/PageHeading' import { useRecorderStore } from '@/hooks/useRecorderStore' import { groupProxyData } from '@/utils/groups' +import { useSetWindowTitle } from '@/hooks/useSetWindowTitle' export function Recorder() { const { proxyData } = useRecorderStore() const [group, setGroup] = useState('Default') useListenProxyData(group) const groupedProxyData = groupProxyData(proxyData) + useSetWindowTitle('Recorder') return ( <> diff --git a/src/views/Validator/Validator.tsx b/src/views/Validator/Validator.tsx index a07bc1ae..a0fcfc37 100644 --- a/src/views/Validator/Validator.tsx +++ b/src/views/Validator/Validator.tsx @@ -3,6 +3,7 @@ import { LogView } from '@/components/LogView' import { WebLogView } from '@/components/WebLogView' import { useListenProxyData } from '@/hooks/useListenProxyData' import { useRecorderStore } from '@/hooks/useRecorderStore' +import { useSetWindowTitle } from '@/hooks/useSetWindowTitle' import { K6Log } from '@/types' import { groupProxyData } from '@/utils/groups' import { Button, Flex, Heading, ScrollArea, Spinner } from '@radix-ui/themes' @@ -13,7 +14,9 @@ export function Validator() { const [isRunning, setIsRunning] = useState(false) const [logs, setLogs] = useState([]) useListenProxyData() - const { proxyData, resetProxyData } = useRecorderStore() + const proxyData = useRecorderStore((store) => store.proxyData) + const resetProxyData = useRecorderStore((store) => store.resetProxyData) + useSetWindowTitle('Validator') const groupedProxyData = groupProxyData(proxyData) diff --git a/vite.base.config.ts b/vite.base.config.ts index 917e7359..c292c915 100644 --- a/vite.base.config.ts +++ b/vite.base.config.ts @@ -65,6 +65,7 @@ export function getBuildDefine(env: ConfigEnv<'build'>) { } return { ...acc, ...def } }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any {} as Record )