summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOskar <oskar@mullvad.net>2024-09-24 13:18:32 +0200
committerOskar <oskar@mullvad.net>2024-09-24 13:18:32 +0200
commit78aea0344617e0e013af49645d3d5563f124df31 (patch)
treeed5371911d23ba2bab8e701f351d822202d63d57
parentcd4f743ed5ce75e975594bf3071074756c538f53 (diff)
parent4bb25616f02af4e15b0140767c07b61e49e8aa83 (diff)
downloadmullvadvpn-78aea0344617e0e013af49645d3d5563f124df31.tar.xz
mullvadvpn-78aea0344617e0e013af49645d3d5563f124df31.zip
Merge branch 'make-eslint-and-other-tools-run-for-all-parts-of-the-project-des-1254'
-rw-r--r--gui/.eslintignore4
-rw-r--r--gui/.eslintrc.js120
-rw-r--r--gui/.prettierignore2
-rw-r--r--gui/.prettierrc.yml11
-rw-r--r--gui/eslint.config.mjs166
-rw-r--r--gui/package-lock.json1337
-rw-r--r--gui/package.json19
-rw-r--r--gui/prettier.config.mjs7
-rw-r--r--gui/scripts/extract-translations.js2
-rw-r--r--gui/scripts/verify-translations-format.ts20
-rw-r--r--gui/src/main/daemon-rpc.ts2
-rw-r--r--gui/src/main/index.ts5
-rw-r--r--gui/src/main/linux-desktop-entry.ts1
-rw-r--r--gui/src/main/linux-split-tunneling.ts4
-rw-r--r--gui/src/main/logging.ts2
-rw-r--r--gui/src/main/user-interface.ts2
-rw-r--r--gui/src/main/windows-split-tunneling.ts2
-rw-r--r--gui/src/renderer/app.tsx2
-rw-r--r--gui/src/renderer/components/ClipboardLabel.tsx2
-rw-r--r--gui/src/renderer/components/EditApiAccessMethod.tsx2
-rw-r--r--gui/src/renderer/components/ImageView.tsx1
-rw-r--r--gui/src/renderer/components/Login.tsx2
-rw-r--r--gui/src/renderer/components/NotificationBanner.tsx2
-rw-r--r--gui/src/renderer/components/ProblemReport.tsx6
-rw-r--r--gui/src/renderer/components/main-view/FeatureIndicators.tsx2
-rw-r--r--gui/src/renderer/lib/ip.ts18
-rw-r--r--gui/tasks/assets.js9
-rw-r--r--gui/tasks/distribution.js96
-rw-r--r--gui/tasks/scripts.js4
-rw-r--r--gui/test/e2e/installed/installed-utils.ts2
-rw-r--r--gui/test/e2e/installed/playwright.config.ts2
-rw-r--r--gui/test/e2e/installed/state-dependent/api-access-methods.spec.ts30
-rw-r--r--gui/test/e2e/installed/state-dependent/custom-bridge.spec.ts73
-rw-r--r--gui/test/e2e/installed/state-dependent/device-revoked.spec.ts8
-rw-r--r--gui/test/e2e/installed/state-dependent/disconnected.spec.ts2
-rw-r--r--gui/test/e2e/installed/state-dependent/location.spec.ts3
-rw-r--r--gui/test/e2e/installed/state-dependent/login.spec.ts72
-rw-r--r--gui/test/e2e/installed/state-dependent/macos-split-tunneling.spec.ts29
-rw-r--r--gui/test/e2e/installed/state-dependent/obfuscation.spec.ts36
-rw-r--r--gui/test/e2e/installed/state-dependent/settings-import.spec.ts64
-rw-r--r--gui/test/e2e/installed/state-dependent/too-many-devices.spec.ts19
-rw-r--r--gui/test/e2e/installed/state-dependent/tunnel-state.spec.ts16
-rw-r--r--gui/test/e2e/mocked/expired-account-error-view.spec.ts23
-rw-r--r--gui/test/e2e/mocked/feature-indicators.spec.ts39
-rw-r--r--gui/test/e2e/mocked/mocked-utils.ts4
-rw-r--r--gui/test/e2e/mocked/settings.spec.ts4
-rw-r--r--gui/test/e2e/mocked/tunnel-state.spec.ts15
-rw-r--r--gui/test/e2e/shared/tunnel-state.ts1
-rw-r--r--gui/test/e2e/utils.ts57
-rw-r--r--gui/test/unit/account-data-cache.spec.ts15
-rw-r--r--gui/test/unit/changelog.spec.ts3
-rw-r--r--gui/test/unit/date-helper.spec.ts88
-rw-r--r--gui/test/unit/history.spec.ts3
-rw-r--r--gui/test/unit/ip.spec.ts3
-rw-r--r--gui/test/unit/keyframe-animation.spec.ts3
-rw-r--r--gui/test/unit/list-diff.spec.ts3
-rw-r--r--gui/test/unit/logging.spec.ts7
-rw-r--r--gui/test/unit/notification-evaluation.spec.ts36
-rw-r--r--gui/test/unit/setup.ts2
-rw-r--r--gui/test/unit/tunnel-state.spec.ts4
60 files changed, 1312 insertions, 1206 deletions
diff --git a/gui/.eslintignore b/gui/.eslintignore
deleted file mode 100644
index 07b7d976c2..0000000000
--- a/gui/.eslintignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.eslintrc.js
-gulpfile.js
-init.js
-tasks/*.js
diff --git a/gui/.eslintrc.js b/gui/.eslintrc.js
deleted file mode 100644
index 4e4b1e0abe..0000000000
--- a/gui/.eslintrc.js
+++ /dev/null
@@ -1,120 +0,0 @@
-const namingConvention = [
- {
- selector: 'default',
- format: ['camelCase'],
- },
- {
- selector: 'variable',
- modifiers: ['const'],
- format: ['camelCase', 'PascalCase', 'UPPER_CASE'],
- leadingUnderscore: 'allow',
- },
- {
- selector: 'variableLike',
- format: ['camelCase'],
- leadingUnderscore: 'allow',
- },
- {
- selector: 'import',
- format: ['camelCase', 'PascalCase', 'snake_case'],
- },
- {
- selector: 'parameter',
- format: ['camelCase', 'PascalCase'],
- leadingUnderscore: 'allow',
- },
- {
- selector: 'function',
- format: ['camelCase', 'PascalCase'],
- },
- {
- selector: 'memberLike',
- format: ['camelCase'],
- },
- {
- selector: 'typeProperty',
- format: ['camelCase'],
- filter: {
- regex: "^(data-testid|aria-labelledby|aria-describedby)$",
- match: false,
- },
- },
- {
- selector: 'typeLike',
- format: ['PascalCase'],
- },
- {
- selector: 'property',
- format: null,
- },
-];
-
-const memberOrdering = {
- default: [
- 'public-field',
- 'protected-field',
- 'private-field',
-
- 'public-constructor',
- 'protected-constructor',
- 'private-constructor',
-
- 'public-method',
- 'protected-method',
- 'private-method',
- ],
-};
-
-module.exports = {
- env: {
- es6: true,
- node: true,
- },
- parserOptions: {
- parser: '@typescript-eslint/parser',
- project: './tsconfig.json',
- tsconfigRootDir: __dirname,
- ecmaVersion: '2018',
- sourceType: 'module',
- ecmaFeatures: {
- jsx: true,
- },
- },
- ignorePatterns: ['test/*', 'scripts/*'],
- plugins: ['prettier', 'simple-import-sort'],
- extends: [
- 'eslint:recommended',
- 'plugin:@typescript-eslint/recommended',
- 'plugin:react/recommended',
- 'plugin:react/jsx-runtime',
- ],
- settings: {
- react: {
- createClass: 'createReactClass',
- pragma: 'React',
- version: 'detect',
- },
- },
- rules: {
- quotes: ['error', 'single', { avoidEscape: true }],
- 'prettier/prettier': 'error',
- '@typescript-eslint/no-unused-vars': [
- 'error',
- { argsIgnorePattern: '^_', ignoreRestSiblings: true },
- ],
- '@typescript-eslint/require-await': 'error',
- '@typescript-eslint/no-floating-promises': 'error',
- '@typescript-eslint/no-unused-expressions': 'error',
- '@typescript-eslint/member-ordering': ['error', memberOrdering],
- 'no-return-await': 'error',
- 'react/jsx-no-bind': 'error',
- '@typescript-eslint/naming-convention': ['error', ...namingConvention],
- '@typescript-eslint/ban-ts-comment': ['error', { 'ts-ignore': false }],
- 'simple-import-sort/imports': 'error',
-
- '@typescript-eslint/no-use-before-define': 'off',
- '@typescript-eslint/explicit-module-boundary-types': 'off',
- '@typescript-eslint/no-non-null-assertion': 'off',
- 'react/prop-types': 'off',
- },
-};
diff --git a/gui/.prettierignore b/gui/.prettierignore
deleted file mode 100644
index b38db2f296..0000000000
--- a/gui/.prettierignore
+++ /dev/null
@@ -1,2 +0,0 @@
-node_modules/
-build/
diff --git a/gui/.prettierrc.yml b/gui/.prettierrc.yml
deleted file mode 100644
index 7c4217913d..0000000000
--- a/gui/.prettierrc.yml
+++ /dev/null
@@ -1,11 +0,0 @@
----
-# .prettierrc.yml
-# see: https://prettier.io/docs/en/options.html
-printWidth: 100
-semi: true
-singleQuote: true
-trailingComma: all
-bracketSpacing: true
-jsxBracketSameLine: true
-arrowParens: always
-proseWrap: always
diff --git a/gui/eslint.config.mjs b/gui/eslint.config.mjs
new file mode 100644
index 0000000000..5c2b5d848c
--- /dev/null
+++ b/gui/eslint.config.mjs
@@ -0,0 +1,166 @@
+import eslint from '@eslint/js';
+import prettier from 'eslint-plugin-prettier/recommended';
+import react from 'eslint-plugin-react';
+import simpleImportSort from 'eslint-plugin-simple-import-sort';
+import globals from 'globals';
+import tseslint from 'typescript-eslint';
+
+const namingConvention = [
+ {
+ selector: 'default',
+ format: ['camelCase'],
+ },
+ {
+ selector: 'variable',
+ modifiers: ['const'],
+ format: ['camelCase', 'PascalCase', 'UPPER_CASE'],
+ leadingUnderscore: 'allow',
+ },
+ {
+ selector: 'variableLike',
+ format: ['camelCase'],
+ leadingUnderscore: 'allow',
+ },
+ {
+ selector: 'import',
+ format: ['camelCase', 'PascalCase', 'snake_case'],
+ },
+ {
+ selector: 'parameter',
+ format: ['camelCase', 'PascalCase'],
+ leadingUnderscore: 'allow',
+ },
+ {
+ selector: 'function',
+ format: ['camelCase', 'PascalCase'],
+ },
+ {
+ selector: 'memberLike',
+ format: ['camelCase'],
+ },
+ {
+ selector: 'typeProperty',
+ format: ['camelCase'],
+ filter: {
+ regex: '^(data-testid|aria-labelledby|aria-describedby)$',
+ match: false,
+ },
+ },
+ {
+ selector: 'typeLike',
+ format: ['PascalCase'],
+ },
+ {
+ selector: 'property',
+ format: null,
+ },
+];
+
+const memberOrdering = {
+ default: [
+ 'public-field',
+ 'protected-field',
+ 'private-field',
+
+ 'public-constructor',
+ 'protected-constructor',
+ 'private-constructor',
+
+ 'public-method',
+ 'protected-method',
+ 'private-method',
+ ],
+};
+
+export default tseslint.config(
+ eslint.configs.recommended,
+ ...tseslint.configs.recommended,
+ react.configs.flat.recommended,
+ prettier,
+ { ignores: ['build/*'] },
+ {
+ settings: {
+ react: {
+ createClass: 'createReactClass',
+ pragma: 'React',
+ version: 'detect',
+ },
+ },
+ },
+ {
+ files: ['**/*'],
+ ignores: ['src/renderer/**/*'],
+ languageOptions: {
+ globals: globals.node,
+ },
+ },
+ {
+ files: ['src/renderer/**/*'],
+ languageOptions: {
+ globals: globals.browser,
+ },
+ },
+ {
+ files: ['test/**/*'],
+ languageOptions: {
+ globals: globals.mocha,
+ },
+ },
+ {
+ files: ['src/**/*.{js,mjs,ts,tsx}'],
+ languageOptions: {
+ parserOptions: {
+ parser: '@typescript-eslint/parser',
+ project: './tsconfig.json',
+ ecmaVersion: '2018',
+ sourceType: 'module',
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+ },
+ rules: {
+ '@typescript-eslint/require-await': 'error',
+ '@typescript-eslint/no-floating-promises': 'error',
+ },
+ },
+ {
+ files: ['**/*.{js,mjs,ts,tsx}'],
+ plugins: {
+ 'simple-import-sort': simpleImportSort,
+ },
+ rules: {
+ quotes: ['error', 'single', { avoidEscape: true }],
+ // 'prettier/prettier': 'error',
+ '@typescript-eslint/no-unused-vars': [
+ 'error',
+ { argsIgnorePattern: '^_', ignoreRestSiblings: true },
+ ],
+ '@typescript-eslint/no-unused-expressions': 'error',
+ '@typescript-eslint/member-ordering': ['error', memberOrdering],
+ 'no-return-await': 'error',
+ 'react/jsx-no-bind': 'error',
+ '@typescript-eslint/naming-convention': ['error', ...namingConvention],
+ '@typescript-eslint/ban-ts-comment': ['error', { 'ts-ignore': false }],
+ 'simple-import-sort/imports': 'error',
+
+ '@typescript-eslint/no-use-before-define': 'off',
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
+ '@typescript-eslint/no-non-null-assertion': 'off',
+ 'react/prop-types': 'off',
+ 'react/react-in-jsx-scope': 'off',
+ },
+ },
+ {
+ files: ['test/**/*.spec.ts'],
+ rules: {
+ '@typescript-eslint/no-unused-expressions': 'off',
+ },
+ },
+ {
+ files: ['tasks/*', 'scripts/*', 'gulpfile.js', 'init.js'],
+ rules: {
+ '@typescript-eslint/no-require-imports': 'off',
+ },
+ },
+);
diff --git a/gui/package-lock.json b/gui/package-lock.json
index d3fa7f4208..6ff861c565 100644
--- a/gui/package-lock.json
+++ b/gui/package-lock.json
@@ -26,10 +26,12 @@
"styled-components": "^6.1.0"
},
"devDependencies": {
+ "@eslint/js": "^9.10.0",
"@playwright/test": "^1.41.1",
"@types/chai": "^4.3.3",
"@types/chai-as-promised": "^7.1.5",
"@types/chai-spies": "^1.0.3",
+ "@types/eslint__js": "^8.42.3",
"@types/gettext-parser": "^4.0.1",
"@types/google-protobuf": "^3.15.6",
"@types/history": "^4.7.11",
@@ -42,8 +44,6 @@
"@types/sinon": "^10.0.13",
"@types/sprintf-js": "^1.1.2",
"@types/topojson-specification": "^1.0.2",
- "@typescript-eslint/eslint-plugin": "^7.13.0",
- "@typescript-eslint/parser": "^7.13.0",
"browserify": "^17.0.0",
"chai": "^4.3.6",
"chai-as-promised": "^7.1.1",
@@ -52,11 +52,13 @@
"electron": "^30.0.4",
"electron-builder": "^24.13.3",
"electron-devtools-installer": "^3.2.0",
- "eslint": "^8.57.0",
- "eslint-plugin-prettier": "^5.1.3",
- "eslint-plugin-react": "^7.34.2",
- "eslint-plugin-simple-import-sort": "^12.1.0",
+ "eslint": "^9.10.0",
+ "eslint-config-prettier": "^9.1.0",
+ "eslint-plugin-prettier": "^5.2.1",
+ "eslint-plugin-react": "^7.36.1",
+ "eslint-plugin-simple-import-sort": "^12.1.1",
"gettext-extractor": "^3.5.4",
+ "globals": "^15.9.0",
"grpc_tools_node_protoc_ts": "^5.3.2",
"gulp": "^4.0.2",
"gulp-inject-string": "^1.1.2",
@@ -65,11 +67,12 @@
"mocha": "^10.2.0",
"playwright": "^1.41.1",
"postject": "^1.0.0-alpha.6",
- "prettier": "^3.3.2",
+ "prettier": "^3.3.3",
"sinon": "^14.0.1",
"ts-node": "^10.9.2",
"tsc-watch": "^5.0.3",
"typescript": "^5.4.5",
+ "typescript-eslint": "^8.6.0",
"vinyl-buffer": "^1.0.1",
"vinyl-source-stream": "^2.0.0",
"xvfb-maybe": "^0.2.1"
@@ -432,24 +435,61 @@
}
},
"node_modules/@eslint-community/regexpp": {
- "version": "4.10.1",
- "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz",
- "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==",
+ "version": "4.11.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz",
+ "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==",
"dev": true,
"engines": {
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
}
},
+ "node_modules/@eslint/config-array": {
+ "version": "0.18.0",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz",
+ "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==",
+ "dev": true,
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.4",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/config-array/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@eslint/config-array/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true
+ },
"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.1.0",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz",
+ "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==",
"dev": true,
"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",
@@ -457,19 +497,19 @@
"strip-json-comments": "^3.1.1"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/@eslint/eslintrc/node_modules/debug": {
- "version": "4.3.5",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
- "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"dev": true,
"dependencies": {
- "ms": "2.1.2"
+ "ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
@@ -480,19 +520,52 @@
}
}
},
+ "node_modules/@eslint/eslintrc/node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/@eslint/eslintrc/node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
},
"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==",
+ "version": "9.10.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.10.0.tgz",
+ "integrity": "sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==",
"dev": true,
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz",
+ "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==",
+ "dev": true,
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.1.0.tgz",
+ "integrity": "sha512-autAXT203ixhqei9xt+qkYOvY8l6LAFIdT2UXc/RPNeUVfqRF1BV94GTJyVPFKT8nFM6MyVJhjLj9E8JWvf5zQ==",
+ "dev": true,
+ "dependencies": {
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@grpc/grpc-js": {
@@ -596,44 +669,6 @@
"node": ">=0.10.0"
}
},
- "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,
- "dependencies": {
- "@humanwhocodes/object-schema": "^2.0.2",
- "debug": "^4.3.1",
- "minimatch": "^3.0.5"
- },
- "engines": {
- "node": ">=10.10.0"
- }
- },
- "node_modules/@humanwhocodes/config-array/node_modules/debug": {
- "version": "4.3.5",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
- "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
- "dev": true,
- "dependencies": {
- "ms": "2.1.2"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/@humanwhocodes/config-array/node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "dev": true
- },
"node_modules/@humanwhocodes/module-importer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
@@ -647,12 +682,18 @@
"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.3.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz",
+ "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==",
+ "dev": true,
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
},
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
@@ -1260,6 +1301,31 @@
"@types/ms": "*"
}
},
+ "node_modules/@types/eslint": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz",
+ "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==",
+ "dev": true,
+ "dependencies": {
+ "@types/estree": "*",
+ "@types/json-schema": "*"
+ }
+ },
+ "node_modules/@types/eslint__js": {
+ "version": "8.42.3",
+ "resolved": "https://registry.npmjs.org/@types/eslint__js/-/eslint__js-8.42.3.tgz",
+ "integrity": "sha512-alfG737uhmPdnvkrLdZLcEKJ/B8s9Y4hrZ+YAdzUeoArBlSUERA2E87ROfOaS4jd/C45fzOoZzidLc1IPwLqOw==",
+ "dev": true,
+ "dependencies": {
+ "@types/eslint": "*"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
+ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
+ "dev": true
+ },
"node_modules/@types/events": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
@@ -1328,6 +1394,12 @@
"integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==",
"dev": true
},
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true
+ },
"node_modules/@types/keyv": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
@@ -1492,31 +1564,31 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.0.tgz",
- "integrity": "sha512-FX1X6AF0w8MdVFLSdqwqN/me2hyhuQg4ykN6ZpVhh1ij/80pTvDKclX1sZB9iqex8SjQfVhwMKs3JtnnMLzG9w==",
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.6.0.tgz",
+ "integrity": "sha512-UOaz/wFowmoh2G6Mr9gw60B1mm0MzUtm6Ic8G2yM1Le6gyj5Loi/N+O5mocugRGY+8OeeKmkMmbxNqUCq3B4Sg==",
"dev": true,
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
- "@typescript-eslint/scope-manager": "7.13.0",
- "@typescript-eslint/type-utils": "7.13.0",
- "@typescript-eslint/utils": "7.13.0",
- "@typescript-eslint/visitor-keys": "7.13.0",
+ "@typescript-eslint/scope-manager": "8.6.0",
+ "@typescript-eslint/type-utils": "8.6.0",
+ "@typescript-eslint/utils": "8.6.0",
+ "@typescript-eslint/visitor-keys": "8.6.0",
"graphemer": "^1.4.0",
"ignore": "^5.3.1",
"natural-compare": "^1.4.0",
"ts-api-utils": "^1.3.0"
},
"engines": {
- "node": "^18.18.0 || >=20.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "@typescript-eslint/parser": "^7.0.0",
- "eslint": "^8.56.0"
+ "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
+ "eslint": "^8.57.0 || ^9.0.0"
},
"peerDependenciesMeta": {
"typescript": {
@@ -1524,26 +1596,27 @@
}
}
},
- "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.0.tgz",
- "integrity": "sha512-xMEtMzxq9eRkZy48XuxlBFzpVMDurUAfDu5Rz16GouAtXm0TaAoTFzqWUFPPuQYXI/CDaH/Bgx/fk/84t/Bc9A==",
+ "node_modules/@typescript-eslint/parser": {
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.6.0.tgz",
+ "integrity": "sha512-eQcbCuA2Vmw45iGfcyG4y6rS7BhWfz9MQuk409WD47qMM+bKCGQWXxvoOs1DUp+T7UBMTtRTVT+kXr7Sh4O9Ow==",
"dev": true,
"dependencies": {
- "@typescript-eslint/typescript-estree": "7.13.0",
- "@typescript-eslint/utils": "7.13.0",
- "debug": "^4.3.4",
- "ts-api-utils": "^1.3.0"
+ "@typescript-eslint/scope-manager": "8.6.0",
+ "@typescript-eslint/types": "8.6.0",
+ "@typescript-eslint/typescript-estree": "8.6.0",
+ "@typescript-eslint/visitor-keys": "8.6.0",
+ "debug": "^4.3.4"
},
"engines": {
- "node": "^18.18.0 || >=20.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^8.56.0"
+ "eslint": "^8.57.0 || ^9.0.0"
},
"peerDependenciesMeta": {
"typescript": {
@@ -1551,35 +1624,13 @@
}
}
},
- "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.0.tgz",
- "integrity": "sha512-jceD8RgdKORVnB4Y6BqasfIkFhl4pajB1wVxrF4akxD2QPM8GNYjgGwEzYS+437ewlqqrg7Dw+6dhdpjMpeBFQ==",
- "dev": true,
- "dependencies": {
- "@eslint-community/eslint-utils": "^4.4.0",
- "@typescript-eslint/scope-manager": "7.13.0",
- "@typescript-eslint/types": "7.13.0",
- "@typescript-eslint/typescript-estree": "7.13.0"
- },
- "engines": {
- "node": "^18.18.0 || >=20.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.56.0"
- }
- },
- "node_modules/@typescript-eslint/eslint-plugin/node_modules/debug": {
- "version": "4.3.5",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
- "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
+ "node_modules/@typescript-eslint/parser/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"dev": true,
"dependencies": {
- "ms": "2.1.2"
+ "ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
@@ -1590,33 +1641,46 @@
}
}
},
- "node_modules/@typescript-eslint/eslint-plugin/node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "node_modules/@typescript-eslint/parser/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
},
- "node_modules/@typescript-eslint/parser": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.13.0.tgz",
- "integrity": "sha512-EjMfl69KOS9awXXe83iRN7oIEXy9yYdqWfqdrFAYAAr6syP8eLEFI7ZE4939antx2mNgPRW/o1ybm2SFYkbTVA==",
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.6.0.tgz",
+ "integrity": "sha512-ZuoutoS5y9UOxKvpc/GkvF4cuEmpokda4wRg64JEia27wX+PysIE9q+lzDtlHHgblwUWwo5/Qn+/WyTUvDwBHw==",
"dev": true,
"dependencies": {
- "@typescript-eslint/scope-manager": "7.13.0",
- "@typescript-eslint/types": "7.13.0",
- "@typescript-eslint/typescript-estree": "7.13.0",
- "@typescript-eslint/visitor-keys": "7.13.0",
- "debug": "^4.3.4"
+ "@typescript-eslint/types": "8.6.0",
+ "@typescript-eslint/visitor-keys": "8.6.0"
},
"engines": {
- "node": "^18.18.0 || >=20.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/type-utils": {
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.6.0.tgz",
+ "integrity": "sha512-dtePl4gsuenXVwC7dVNlb4mGDcKjDT/Ropsk4za/ouMBPplCLyznIaR+W65mvCvsyS97dymoBRrioEXI7k0XIg==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/typescript-estree": "8.6.0",
+ "@typescript-eslint/utils": "8.6.0",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^1.3.0"
},
- "peerDependencies": {
- "eslint": "^8.56.0"
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
},
"peerDependenciesMeta": {
"typescript": {
@@ -1624,13 +1688,13 @@
}
}
},
- "node_modules/@typescript-eslint/parser/node_modules/debug": {
- "version": "4.3.5",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
- "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
+ "node_modules/@typescript-eslint/type-utils/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"dev": true,
"dependencies": {
- "ms": "2.1.2"
+ "ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
@@ -1641,36 +1705,19 @@
}
}
},
- "node_modules/@typescript-eslint/parser/node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "node_modules/@typescript-eslint/type-utils/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
},
- "node_modules/@typescript-eslint/scope-manager": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.0.tgz",
- "integrity": "sha512-ZrMCe1R6a01T94ilV13egvcnvVJ1pxShkE0+NDjDzH4nvG1wXpwsVI5bZCvE7AEDH1mXEx5tJSVR68bLgG7Dng==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/types": "7.13.0",
- "@typescript-eslint/visitor-keys": "7.13.0"
- },
- "engines": {
- "node": "^18.18.0 || >=20.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
"node_modules/@typescript-eslint/types": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.0.tgz",
- "integrity": "sha512-QWuwm9wcGMAuTsxP+qz6LBBd3Uq8I5Nv8xb0mk54jmNoCyDspnMvVsOxI6IsMmway5d1S9Su2+sCKv1st2l6eA==",
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.6.0.tgz",
+ "integrity": "sha512-rojqFZGd4MQxw33SrOy09qIDS8WEldM8JWtKQLAjf/X5mGSeEFh5ixQlxssMNyPslVIk9yzWqXCsV2eFhYrYUw==",
"dev": true,
"engines": {
- "node": "^18.18.0 || >=20.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
@@ -1678,22 +1725,22 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.0.tgz",
- "integrity": "sha512-cAvBvUoobaoIcoqox1YatXOnSl3gx92rCZoMRPzMNisDiM12siGilSM4+dJAekuuHTibI2hVC2fYK79iSFvWjw==",
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.6.0.tgz",
+ "integrity": "sha512-MOVAzsKJIPIlLK239l5s06YXjNqpKTVhBVDnqUumQJja5+Y94V3+4VUFRA0G60y2jNnTVwRCkhyGQpavfsbq/g==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "7.13.0",
- "@typescript-eslint/visitor-keys": "7.13.0",
+ "@typescript-eslint/types": "8.6.0",
+ "@typescript-eslint/visitor-keys": "8.6.0",
"debug": "^4.3.4",
- "globby": "^11.1.0",
+ "fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
"minimatch": "^9.0.4",
"semver": "^7.6.0",
"ts-api-utils": "^1.3.0"
},
"engines": {
- "node": "^18.18.0 || >=20.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
@@ -1715,12 +1762,12 @@
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/debug": {
- "version": "4.3.5",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
- "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"dev": true,
"dependencies": {
- "ms": "2.1.2"
+ "ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
@@ -1732,9 +1779,9 @@
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
- "version": "9.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
- "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
@@ -1747,34 +1794,50 @@
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
},
+ "node_modules/@typescript-eslint/utils": {
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.6.0.tgz",
+ "integrity": "sha512-eNp9cWnYf36NaOVjkEUznf6fEgVy1TWpE0o52e4wtojjBx7D1UV2WAWGzR+8Y5lVFtpMLPwNbC67T83DWSph4A==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "@typescript-eslint/scope-manager": "8.6.0",
+ "@typescript-eslint/types": "8.6.0",
+ "@typescript-eslint/typescript-estree": "8.6.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0"
+ }
+ },
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.0.tgz",
- "integrity": "sha512-nxn+dozQx+MK61nn/JP+M4eCkHDSxSLDpgE3WcQo0+fkjEolnaB5jswvIKC4K56By8MMgIho7f1PVxERHEo8rw==",
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.6.0.tgz",
+ "integrity": "sha512-wapVFfZg9H0qOYh4grNVQiMklJGluQrOUiOhYRrQWhx7BY/+I1IYb8BczWNbbUpO+pqy0rDciv3lQH5E1bCLrg==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "7.13.0",
+ "@typescript-eslint/types": "8.6.0",
"eslint-visitor-keys": "^3.4.3"
},
"engines": {
- "node": "^18.18.0 || >=20.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/@xmldom/xmldom": {
"version": "0.8.10",
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
@@ -2356,15 +2419,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/array-union": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
- "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/array-unique": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
@@ -2412,18 +2466,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/array.prototype.toreversed": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz",
- "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==",
- "dev": true,
- "dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1",
- "es-shim-unscopables": "^1.0.0"
- }
- },
"node_modules/array.prototype.tosorted": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz",
@@ -4518,27 +4560,6 @@
"minimatch": "^3.0.4"
}
},
- "node_modules/dir-glob": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
- "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
- "dev": true,
- "dependencies": {
- "path-type": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/dir-glob/node_modules/path-type": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
- "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/dmg-builder": {
"version": "24.13.3",
"resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-24.13.3.tgz",
@@ -5063,43 +5084,39 @@
}
},
"node_modules/eslint": {
- "version": "8.57.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
- "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
+ "version": "9.10.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.10.0.tgz",
+ "integrity": "sha512-Y4D0IgtBZfOcOUAIQTSXBKoNGfY0REGqHJG6+Q81vNippW5YlKjHFj4soMxamKK1NXHUWuBZTLdU3Km+L/pcHw==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
- "@eslint-community/regexpp": "^4.6.1",
- "@eslint/eslintrc": "^2.1.4",
- "@eslint/js": "8.57.0",
- "@humanwhocodes/config-array": "^0.11.14",
+ "@eslint-community/regexpp": "^4.11.0",
+ "@eslint/config-array": "^0.18.0",
+ "@eslint/eslintrc": "^3.1.0",
+ "@eslint/js": "9.10.0",
+ "@eslint/plugin-kit": "^0.1.0",
"@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.3.0",
"@nodelib/fs.walk": "^1.2.8",
- "@ungap/structured-clone": "^1.2.0",
"ajv": "^6.12.4",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
"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.0.2",
+ "eslint-visitor-keys": "^4.0.0",
+ "espree": "^10.1.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",
@@ -5111,20 +5128,40 @@
"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": "9.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
+ "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
+ "dev": true,
+ "bin": {
+ "eslint-config-prettier": "bin/cli.js"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.0.0"
}
},
"node_modules/eslint-plugin-prettier": {
- "version": "5.1.3",
- "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz",
- "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==",
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz",
+ "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==",
"dev": true,
"dependencies": {
"prettier-linter-helpers": "^1.0.0",
- "synckit": "^0.8.6"
+ "synckit": "^0.9.1"
},
"engines": {
"node": "^14.18.0 || >=16.0.0"
@@ -5148,35 +5185,35 @@
}
},
"node_modules/eslint-plugin-react": {
- "version": "7.34.2",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.2.tgz",
- "integrity": "sha512-2HCmrU+/JNigDN6tg55cRDKCQWicYAPB38JGSFDQt95jDm8rrvSUo7YPkOIm5l6ts1j1zCvysNcasvfTMQzUOw==",
+ "version": "7.36.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.36.1.tgz",
+ "integrity": "sha512-/qwbqNXZoq+VP30s1d4Nc1C5GTxjJQjk4Jzs4Wq2qzxFM7dSmuG2UkIjg2USMLh3A/aVcUNrK7v0J5U1XEGGwA==",
"dev": true,
"dependencies": {
"array-includes": "^3.1.8",
"array.prototype.findlast": "^1.2.5",
"array.prototype.flatmap": "^1.3.2",
- "array.prototype.toreversed": "^1.1.2",
- "array.prototype.tosorted": "^1.1.3",
+ "array.prototype.tosorted": "^1.1.4",
"doctrine": "^2.1.0",
"es-iterator-helpers": "^1.0.19",
"estraverse": "^5.3.0",
+ "hasown": "^2.0.2",
"jsx-ast-utils": "^2.4.1 || ^3.0.0",
"minimatch": "^3.1.2",
"object.entries": "^1.1.8",
"object.fromentries": "^2.0.8",
- "object.hasown": "^1.1.4",
"object.values": "^1.2.0",
"prop-types": "^15.8.1",
"resolve": "^2.0.0-next.5",
"semver": "^6.3.1",
- "string.prototype.matchall": "^4.0.11"
+ "string.prototype.matchall": "^4.0.11",
+ "string.prototype.repeat": "^1.0.0"
},
"engines": {
"node": ">=4"
},
"peerDependencies": {
- "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8"
+ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7"
}
},
"node_modules/eslint-plugin-react/node_modules/resolve": {
@@ -5206,25 +5243,25 @@
}
},
"node_modules/eslint-plugin-simple-import-sort": {
- "version": "12.1.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.0.tgz",
- "integrity": "sha512-Y2fqAfC11TcG/WP3TrI1Gi3p3nc8XJyEOJYHyEPEGI/UAgNx6akxxlX74p7SbAQdLcgASKhj8M0GKvH3vq/+ig==",
+ "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,
"peerDependencies": {
"eslint": ">=5.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==",
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz",
+ "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==",
"dev": true,
"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"
@@ -5268,16 +5305,16 @@
}
}
},
- "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==",
+ "node_modules/eslint/node_modules/eslint-visitor-keys": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz",
+ "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==",
"dev": true,
- "dependencies": {
- "esutils": "^2.0.2"
- },
"engines": {
- "node": ">=6.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint/node_modules/find-up": {
@@ -5357,26 +5394,26 @@
"dev": true
},
"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==",
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz",
+ "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==",
"dev": true,
"dependencies": {
- "acorn": "^8.9.0",
+ "acorn": "^8.12.0",
"acorn-jsx": "^5.3.2",
- "eslint-visitor-keys": "^3.4.1"
+ "eslint-visitor-keys": "^4.0.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/espree/node_modules/acorn": {
- "version": "8.12.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz",
- "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==",
+ "version": "8.12.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
+ "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
@@ -5385,6 +5422,18 @@
"node": ">=0.4.0"
}
},
+ "node_modules/espree/node_modules/eslint-visitor-keys": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz",
+ "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==",
+ "dev": true,
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
"node_modules/esquery": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
@@ -5862,15 +5911,15 @@
}
},
"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,
"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-uri-to-path": {
@@ -6000,17 +6049,16 @@
}
},
"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,
"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": {
@@ -6554,15 +6602,12 @@
}
},
"node_modules/globals": {
- "version": "13.24.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
- "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+ "version": "15.9.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz",
+ "integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==",
"dev": true,
- "dependencies": {
- "type-fest": "^0.20.2"
- },
"engines": {
- "node": ">=8"
+ "node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@@ -6583,26 +6628,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/globby": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
- "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
- "dev": true,
- "dependencies": {
- "array-union": "^2.1.0",
- "dir-glob": "^3.0.1",
- "fast-glob": "^3.2.9",
- "ignore": "^5.2.0",
- "merge2": "^1.4.1",
- "slash": "^3.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/glogg": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz",
@@ -9624,23 +9649,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/object.hasown": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz",
- "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==",
- "dev": true,
- "dependencies": {
- "define-properties": "^1.2.1",
- "es-abstract": "^1.23.2",
- "es-object-atoms": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/object.map": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz",
@@ -10301,9 +10309,9 @@
}
},
"node_modules/prettier": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz",
- "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==",
+ "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"
@@ -11463,15 +11471,6 @@
"node": ">=8"
}
},
- "node_modules/slash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
- "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/slice-ansi": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz",
@@ -12002,6 +12001,16 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/string.prototype.repeat": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz",
+ "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5"
+ }
+ },
"node_modules/string.prototype.trim": {
"version": "1.2.9",
"resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz",
@@ -12281,9 +12290,9 @@
}
},
"node_modules/synckit": {
- "version": "0.8.8",
- "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz",
- "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==",
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz",
+ "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==",
"dev": true,
"dependencies": {
"@pkgr/core": "^0.1.0",
@@ -12771,18 +12780,6 @@
"node": ">=4"
}
},
- "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,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/typed-array-buffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz",
@@ -12875,6 +12872,29 @@
"node": ">=14.17"
}
},
+ "node_modules/typescript-eslint": {
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.6.0.tgz",
+ "integrity": "sha512-eEhhlxCEpCd4helh3AO1hk0UP2MvbRi9CtIAJTVPQjuSXOOO2jsEacNi4UdcJzZJbeuVg1gMhtZ8UYb+NFYPrA==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/eslint-plugin": "8.6.0",
+ "@typescript-eslint/parser": "8.6.0",
+ "@typescript-eslint/utils": "8.6.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
"node_modules/uglify-js": {
"version": "3.13.6",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.6.tgz",
@@ -14089,21 +14109,49 @@
}
},
"@eslint-community/regexpp": {
- "version": "4.10.1",
- "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz",
- "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==",
+ "version": "4.11.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz",
+ "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==",
"dev": true
},
+ "@eslint/config-array": {
+ "version": "0.18.0",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz",
+ "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==",
+ "dev": true,
+ "requires": {
+ "@eslint/object-schema": "^2.1.4",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.3"
+ }
+ },
+ "ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true
+ }
+ }
+ },
"@eslint/eslintrc": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
- "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz",
+ "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==",
"dev": true,
"requires": {
"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",
@@ -14112,28 +14160,49 @@
},
"dependencies": {
"debug": {
- "version": "4.3.5",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
- "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"dev": true,
"requires": {
- "ms": "2.1.2"
+ "ms": "^2.1.3"
}
},
+ "globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true
+ },
"ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
}
}
},
"@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==",
+ "version": "9.10.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.10.0.tgz",
+ "integrity": "sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==",
"dev": true
},
+ "@eslint/object-schema": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz",
+ "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==",
+ "dev": true
+ },
+ "@eslint/plugin-kit": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.1.0.tgz",
+ "integrity": "sha512-autAXT203ixhqei9xt+qkYOvY8l6LAFIdT2UXc/RPNeUVfqRF1BV94GTJyVPFKT8nFM6MyVJhjLj9E8JWvf5zQ==",
+ "dev": true,
+ "requires": {
+ "levn": "^0.4.1"
+ }
+ },
"@grpc/grpc-js": {
"version": "1.11.2",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.11.2.tgz",
@@ -14212,44 +14281,16 @@
}
}
},
- "@humanwhocodes/config-array": {
- "version": "0.11.14",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
- "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
- "dev": true,
- "requires": {
- "@humanwhocodes/object-schema": "^2.0.2",
- "debug": "^4.3.1",
- "minimatch": "^3.0.5"
- },
- "dependencies": {
- "debug": {
- "version": "4.3.5",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
- "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
- "dev": true,
- "requires": {
- "ms": "2.1.2"
- }
- },
- "ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "dev": true
- }
- }
- },
"@humanwhocodes/module-importer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
"integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
"dev": true
},
- "@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==",
+ "@humanwhocodes/retry": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz",
+ "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==",
"dev": true
},
"@isaacs/cliui": {
@@ -14731,6 +14772,31 @@
"@types/ms": "*"
}
},
+ "@types/eslint": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz",
+ "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==",
+ "dev": true,
+ "requires": {
+ "@types/estree": "*",
+ "@types/json-schema": "*"
+ }
+ },
+ "@types/eslint__js": {
+ "version": "8.42.3",
+ "resolved": "https://registry.npmjs.org/@types/eslint__js/-/eslint__js-8.42.3.tgz",
+ "integrity": "sha512-alfG737uhmPdnvkrLdZLcEKJ/B8s9Y4hrZ+YAdzUeoArBlSUERA2E87ROfOaS4jd/C45fzOoZzidLc1IPwLqOw==",
+ "dev": true,
+ "requires": {
+ "@types/eslint": "*"
+ }
+ },
+ "@types/estree": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
+ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
+ "dev": true
+ },
"@types/events": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
@@ -14799,6 +14865,12 @@
"integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==",
"dev": true
},
+ "@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true
+ },
"@types/keyv": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
@@ -14963,119 +15035,107 @@
}
},
"@typescript-eslint/eslint-plugin": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.0.tgz",
- "integrity": "sha512-FX1X6AF0w8MdVFLSdqwqN/me2hyhuQg4ykN6ZpVhh1ij/80pTvDKclX1sZB9iqex8SjQfVhwMKs3JtnnMLzG9w==",
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.6.0.tgz",
+ "integrity": "sha512-UOaz/wFowmoh2G6Mr9gw60B1mm0MzUtm6Ic8G2yM1Le6gyj5Loi/N+O5mocugRGY+8OeeKmkMmbxNqUCq3B4Sg==",
"dev": true,
"requires": {
"@eslint-community/regexpp": "^4.10.0",
- "@typescript-eslint/scope-manager": "7.13.0",
- "@typescript-eslint/type-utils": "7.13.0",
- "@typescript-eslint/utils": "7.13.0",
- "@typescript-eslint/visitor-keys": "7.13.0",
+ "@typescript-eslint/scope-manager": "8.6.0",
+ "@typescript-eslint/type-utils": "8.6.0",
+ "@typescript-eslint/utils": "8.6.0",
+ "@typescript-eslint/visitor-keys": "8.6.0",
"graphemer": "^1.4.0",
"ignore": "^5.3.1",
"natural-compare": "^1.4.0",
"ts-api-utils": "^1.3.0"
+ }
+ },
+ "@typescript-eslint/parser": {
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.6.0.tgz",
+ "integrity": "sha512-eQcbCuA2Vmw45iGfcyG4y6rS7BhWfz9MQuk409WD47qMM+bKCGQWXxvoOs1DUp+T7UBMTtRTVT+kXr7Sh4O9Ow==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/scope-manager": "8.6.0",
+ "@typescript-eslint/types": "8.6.0",
+ "@typescript-eslint/typescript-estree": "8.6.0",
+ "@typescript-eslint/visitor-keys": "8.6.0",
+ "debug": "^4.3.4"
},
"dependencies": {
- "@typescript-eslint/type-utils": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.0.tgz",
- "integrity": "sha512-xMEtMzxq9eRkZy48XuxlBFzpVMDurUAfDu5Rz16GouAtXm0TaAoTFzqWUFPPuQYXI/CDaH/Bgx/fk/84t/Bc9A==",
- "dev": true,
- "requires": {
- "@typescript-eslint/typescript-estree": "7.13.0",
- "@typescript-eslint/utils": "7.13.0",
- "debug": "^4.3.4",
- "ts-api-utils": "^1.3.0"
- }
- },
- "@typescript-eslint/utils": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.0.tgz",
- "integrity": "sha512-jceD8RgdKORVnB4Y6BqasfIkFhl4pajB1wVxrF4akxD2QPM8GNYjgGwEzYS+437ewlqqrg7Dw+6dhdpjMpeBFQ==",
- "dev": true,
- "requires": {
- "@eslint-community/eslint-utils": "^4.4.0",
- "@typescript-eslint/scope-manager": "7.13.0",
- "@typescript-eslint/types": "7.13.0",
- "@typescript-eslint/typescript-estree": "7.13.0"
- }
- },
"debug": {
- "version": "4.3.5",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
- "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"dev": true,
"requires": {
- "ms": "2.1.2"
+ "ms": "^2.1.3"
}
},
"ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
}
}
},
- "@typescript-eslint/parser": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.13.0.tgz",
- "integrity": "sha512-EjMfl69KOS9awXXe83iRN7oIEXy9yYdqWfqdrFAYAAr6syP8eLEFI7ZE4939antx2mNgPRW/o1ybm2SFYkbTVA==",
+ "@typescript-eslint/scope-manager": {
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.6.0.tgz",
+ "integrity": "sha512-ZuoutoS5y9UOxKvpc/GkvF4cuEmpokda4wRg64JEia27wX+PysIE9q+lzDtlHHgblwUWwo5/Qn+/WyTUvDwBHw==",
"dev": true,
"requires": {
- "@typescript-eslint/scope-manager": "7.13.0",
- "@typescript-eslint/types": "7.13.0",
- "@typescript-eslint/typescript-estree": "7.13.0",
- "@typescript-eslint/visitor-keys": "7.13.0",
- "debug": "^4.3.4"
+ "@typescript-eslint/types": "8.6.0",
+ "@typescript-eslint/visitor-keys": "8.6.0"
+ }
+ },
+ "@typescript-eslint/type-utils": {
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.6.0.tgz",
+ "integrity": "sha512-dtePl4gsuenXVwC7dVNlb4mGDcKjDT/Ropsk4za/ouMBPplCLyznIaR+W65mvCvsyS97dymoBRrioEXI7k0XIg==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/typescript-estree": "8.6.0",
+ "@typescript-eslint/utils": "8.6.0",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^1.3.0"
},
"dependencies": {
"debug": {
- "version": "4.3.5",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
- "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"dev": true,
"requires": {
- "ms": "2.1.2"
+ "ms": "^2.1.3"
}
},
"ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
}
}
},
- "@typescript-eslint/scope-manager": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.0.tgz",
- "integrity": "sha512-ZrMCe1R6a01T94ilV13egvcnvVJ1pxShkE0+NDjDzH4nvG1wXpwsVI5bZCvE7AEDH1mXEx5tJSVR68bLgG7Dng==",
- "dev": true,
- "requires": {
- "@typescript-eslint/types": "7.13.0",
- "@typescript-eslint/visitor-keys": "7.13.0"
- }
- },
"@typescript-eslint/types": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.0.tgz",
- "integrity": "sha512-QWuwm9wcGMAuTsxP+qz6LBBd3Uq8I5Nv8xb0mk54jmNoCyDspnMvVsOxI6IsMmway5d1S9Su2+sCKv1st2l6eA==",
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.6.0.tgz",
+ "integrity": "sha512-rojqFZGd4MQxw33SrOy09qIDS8WEldM8JWtKQLAjf/X5mGSeEFh5ixQlxssMNyPslVIk9yzWqXCsV2eFhYrYUw==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.0.tgz",
- "integrity": "sha512-cAvBvUoobaoIcoqox1YatXOnSl3gx92rCZoMRPzMNisDiM12siGilSM4+dJAekuuHTibI2hVC2fYK79iSFvWjw==",
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.6.0.tgz",
+ "integrity": "sha512-MOVAzsKJIPIlLK239l5s06YXjNqpKTVhBVDnqUumQJja5+Y94V3+4VUFRA0G60y2jNnTVwRCkhyGQpavfsbq/g==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "7.13.0",
- "@typescript-eslint/visitor-keys": "7.13.0",
+ "@typescript-eslint/types": "8.6.0",
+ "@typescript-eslint/visitor-keys": "8.6.0",
"debug": "^4.3.4",
- "globby": "^11.1.0",
+ "fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
"minimatch": "^9.0.4",
"semver": "^7.6.0",
@@ -15092,47 +15152,53 @@
}
},
"debug": {
- "version": "4.3.5",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
- "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"dev": true,
"requires": {
- "ms": "2.1.2"
+ "ms": "^2.1.3"
}
},
"minimatch": {
- "version": "9.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
- "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"requires": {
"brace-expansion": "^2.0.1"
}
},
"ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
}
}
},
+ "@typescript-eslint/utils": {
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.6.0.tgz",
+ "integrity": "sha512-eNp9cWnYf36NaOVjkEUznf6fEgVy1TWpE0o52e4wtojjBx7D1UV2WAWGzR+8Y5lVFtpMLPwNbC67T83DWSph4A==",
+ "dev": true,
+ "requires": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "@typescript-eslint/scope-manager": "8.6.0",
+ "@typescript-eslint/types": "8.6.0",
+ "@typescript-eslint/typescript-estree": "8.6.0"
+ }
+ },
"@typescript-eslint/visitor-keys": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.0.tgz",
- "integrity": "sha512-nxn+dozQx+MK61nn/JP+M4eCkHDSxSLDpgE3WcQo0+fkjEolnaB5jswvIKC4K56By8MMgIho7f1PVxERHEo8rw==",
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.6.0.tgz",
+ "integrity": "sha512-wapVFfZg9H0qOYh4grNVQiMklJGluQrOUiOhYRrQWhx7BY/+I1IYb8BczWNbbUpO+pqy0rDciv3lQH5E1bCLrg==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "7.13.0",
+ "@typescript-eslint/types": "8.6.0",
"eslint-visitor-keys": "^3.4.3"
}
},
- "@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
- },
"@xmldom/xmldom": {
"version": "0.8.10",
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
@@ -15590,12 +15656,6 @@
}
}
},
- "array-union": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
- "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
- "dev": true
- },
"array-unique": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
@@ -15628,18 +15688,6 @@
"es-shim-unscopables": "^1.0.0"
}
},
- "array.prototype.toreversed": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz",
- "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==",
- "dev": true,
- "requires": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1",
- "es-shim-unscopables": "^1.0.0"
- }
- },
"array.prototype.tosorted": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz",
@@ -17376,23 +17424,6 @@
"minimatch": "^3.0.4"
}
},
- "dir-glob": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
- "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
- "dev": true,
- "requires": {
- "path-type": "^4.0.0"
- },
- "dependencies": {
- "path-type": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
- "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
- "dev": true
- }
- }
- },
"dmg-builder": {
"version": "24.13.3",
"resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-24.13.3.tgz",
@@ -17835,43 +17866,39 @@
"dev": true
},
"eslint": {
- "version": "8.57.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
- "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
+ "version": "9.10.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.10.0.tgz",
+ "integrity": "sha512-Y4D0IgtBZfOcOUAIQTSXBKoNGfY0REGqHJG6+Q81vNippW5YlKjHFj4soMxamKK1NXHUWuBZTLdU3Km+L/pcHw==",
"dev": true,
"requires": {
"@eslint-community/eslint-utils": "^4.2.0",
- "@eslint-community/regexpp": "^4.6.1",
- "@eslint/eslintrc": "^2.1.4",
- "@eslint/js": "8.57.0",
- "@humanwhocodes/config-array": "^0.11.14",
+ "@eslint-community/regexpp": "^4.11.0",
+ "@eslint/config-array": "^0.18.0",
+ "@eslint/eslintrc": "^3.1.0",
+ "@eslint/js": "9.10.0",
+ "@eslint/plugin-kit": "^0.1.0",
"@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.3.0",
"@nodelib/fs.walk": "^1.2.8",
- "@ungap/structured-clone": "^1.2.0",
"ajv": "^6.12.4",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
"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.0.2",
+ "eslint-visitor-keys": "^4.0.0",
+ "espree": "^10.1.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",
@@ -17895,14 +17922,11 @@
"ms": "2.1.2"
}
},
- "doctrine": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
- "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
- "dev": true,
- "requires": {
- "esutils": "^2.0.2"
- }
+ "eslint-visitor-keys": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz",
+ "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==",
+ "dev": true
},
"find-up": {
"version": "5.0.0",
@@ -17946,40 +17970,47 @@
}
}
},
+ "eslint-config-prettier": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
+ "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
+ "dev": true,
+ "requires": {}
+ },
"eslint-plugin-prettier": {
- "version": "5.1.3",
- "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz",
- "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==",
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz",
+ "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==",
"dev": true,
"requires": {
"prettier-linter-helpers": "^1.0.0",
- "synckit": "^0.8.6"
+ "synckit": "^0.9.1"
}
},
"eslint-plugin-react": {
- "version": "7.34.2",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.2.tgz",
- "integrity": "sha512-2HCmrU+/JNigDN6tg55cRDKCQWicYAPB38JGSFDQt95jDm8rrvSUo7YPkOIm5l6ts1j1zCvysNcasvfTMQzUOw==",
+ "version": "7.36.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.36.1.tgz",
+ "integrity": "sha512-/qwbqNXZoq+VP30s1d4Nc1C5GTxjJQjk4Jzs4Wq2qzxFM7dSmuG2UkIjg2USMLh3A/aVcUNrK7v0J5U1XEGGwA==",
"dev": true,
"requires": {
"array-includes": "^3.1.8",
"array.prototype.findlast": "^1.2.5",
"array.prototype.flatmap": "^1.3.2",
- "array.prototype.toreversed": "^1.1.2",
- "array.prototype.tosorted": "^1.1.3",
+ "array.prototype.tosorted": "^1.1.4",
"doctrine": "^2.1.0",
"es-iterator-helpers": "^1.0.19",
"estraverse": "^5.3.0",
+ "hasown": "^2.0.2",
"jsx-ast-utils": "^2.4.1 || ^3.0.0",
"minimatch": "^3.1.2",
"object.entries": "^1.1.8",
"object.fromentries": "^2.0.8",
- "object.hasown": "^1.1.4",
"object.values": "^1.2.0",
"prop-types": "^15.8.1",
"resolve": "^2.0.0-next.5",
"semver": "^6.3.1",
- "string.prototype.matchall": "^4.0.11"
+ "string.prototype.matchall": "^4.0.11",
+ "string.prototype.repeat": "^1.0.0"
},
"dependencies": {
"resolve": {
@@ -18002,16 +18033,16 @@
}
},
"eslint-plugin-simple-import-sort": {
- "version": "12.1.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.0.tgz",
- "integrity": "sha512-Y2fqAfC11TcG/WP3TrI1Gi3p3nc8XJyEOJYHyEPEGI/UAgNx6akxxlX74p7SbAQdLcgASKhj8M0GKvH3vq/+ig==",
+ "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,
"requires": {}
},
"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.0.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz",
+ "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==",
"dev": true,
"requires": {
"esrecurse": "^4.3.0",
@@ -18045,20 +18076,26 @@
}
},
"espree": {
- "version": "9.6.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
- "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz",
+ "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==",
"dev": true,
"requires": {
- "acorn": "^8.9.0",
+ "acorn": "^8.12.0",
"acorn-jsx": "^5.3.2",
- "eslint-visitor-keys": "^3.4.1"
+ "eslint-visitor-keys": "^4.0.0"
},
"dependencies": {
"acorn": {
- "version": "8.12.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz",
- "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==",
+ "version": "8.12.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
+ "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
+ "dev": true
+ },
+ "eslint-visitor-keys": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz",
+ "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==",
"dev": true
}
}
@@ -18455,12 +18492,12 @@
}
},
"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,
"requires": {
- "flat-cache": "^3.0.4"
+ "flat-cache": "^4.0.0"
}
},
"file-uri-to-path": {
@@ -18570,14 +18607,13 @@
"dev": true
},
"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,
"requires": {
"flatted": "^3.2.9",
- "keyv": "^4.5.3",
- "rimraf": "^3.0.2"
+ "keyv": "^4.5.4"
}
},
"flatted": {
@@ -18987,13 +19023,10 @@
}
},
"globals": {
- "version": "13.24.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
- "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
- "dev": true,
- "requires": {
- "type-fest": "^0.20.2"
- }
+ "version": "15.9.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz",
+ "integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==",
+ "dev": true
},
"globalthis": {
"version": "1.0.3",
@@ -19004,20 +19037,6 @@
"define-properties": "^1.1.3"
}
},
- "globby": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
- "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
- "dev": true,
- "requires": {
- "array-union": "^2.1.0",
- "dir-glob": "^3.0.1",
- "fast-glob": "^3.2.9",
- "ignore": "^5.2.0",
- "merge2": "^1.4.1",
- "slash": "^3.0.0"
- }
- },
"glogg": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz",
@@ -21338,17 +21357,6 @@
"es-object-atoms": "^1.0.0"
}
},
- "object.hasown": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz",
- "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==",
- "dev": true,
- "requires": {
- "define-properties": "^1.2.1",
- "es-abstract": "^1.23.2",
- "es-object-atoms": "^1.0.0"
- }
- },
"object.map": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz",
@@ -21836,9 +21844,9 @@
"dev": true
},
"prettier": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz",
- "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==",
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz",
+ "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==",
"dev": true
},
"prettier-linter-helpers": {
@@ -22760,12 +22768,6 @@
}
}
},
- "slash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
- "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
- "dev": true
- },
"slice-ansi": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz",
@@ -23213,6 +23215,16 @@
"side-channel": "^1.0.6"
}
},
+ "string.prototype.repeat": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz",
+ "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5"
+ }
+ },
"string.prototype.trim": {
"version": "1.2.9",
"resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz",
@@ -23398,9 +23410,9 @@
}
},
"synckit": {
- "version": "0.8.8",
- "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz",
- "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==",
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz",
+ "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==",
"dev": true,
"requires": {
"@pkgr/core": "^0.1.0",
@@ -23773,12 +23785,6 @@
"integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
"dev": true
},
- "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
- },
"typed-array-buffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz",
@@ -23843,6 +23849,17 @@
"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
"dev": true
},
+ "typescript-eslint": {
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.6.0.tgz",
+ "integrity": "sha512-eEhhlxCEpCd4helh3AO1hk0UP2MvbRi9CtIAJTVPQjuSXOOO2jsEacNi4UdcJzZJbeuVg1gMhtZ8UYb+NFYPrA==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/eslint-plugin": "8.6.0",
+ "@typescript-eslint/parser": "8.6.0",
+ "@typescript-eslint/utils": "8.6.0"
+ }
+ },
"uglify-js": {
"version": "3.13.6",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.6.tgz",
diff --git a/gui/package.json b/gui/package.json
index 0e0fa86d63..457a5a97d1 100644
--- a/gui/package.json
+++ b/gui/package.json
@@ -32,10 +32,12 @@
"nseventmonitor": "^1.0.5"
},
"devDependencies": {
+ "@eslint/js": "^9.10.0",
"@playwright/test": "^1.41.1",
"@types/chai": "^4.3.3",
"@types/chai-as-promised": "^7.1.5",
"@types/chai-spies": "^1.0.3",
+ "@types/eslint__js": "^8.42.3",
"@types/gettext-parser": "^4.0.1",
"@types/google-protobuf": "^3.15.6",
"@types/history": "^4.7.11",
@@ -48,8 +50,6 @@
"@types/sinon": "^10.0.13",
"@types/sprintf-js": "^1.1.2",
"@types/topojson-specification": "^1.0.2",
- "@typescript-eslint/eslint-plugin": "^7.13.0",
- "@typescript-eslint/parser": "^7.13.0",
"browserify": "^17.0.0",
"chai": "^4.3.6",
"chai-as-promised": "^7.1.1",
@@ -58,11 +58,13 @@
"electron": "^30.0.4",
"electron-builder": "^24.13.3",
"electron-devtools-installer": "^3.2.0",
- "eslint": "^8.57.0",
- "eslint-plugin-prettier": "^5.1.3",
- "eslint-plugin-react": "^7.34.2",
- "eslint-plugin-simple-import-sort": "^12.1.0",
+ "eslint": "^9.10.0",
+ "eslint-config-prettier": "^9.1.0",
+ "eslint-plugin-prettier": "^5.2.1",
+ "eslint-plugin-react": "^7.36.1",
+ "eslint-plugin-simple-import-sort": "^12.1.1",
"gettext-extractor": "^3.5.4",
+ "globals": "^15.9.0",
"grpc_tools_node_protoc_ts": "^5.3.2",
"gulp": "^4.0.2",
"gulp-inject-string": "^1.1.2",
@@ -71,11 +73,12 @@
"mocha": "^10.2.0",
"playwright": "^1.41.1",
"postject": "^1.0.0-alpha.6",
- "prettier": "^3.3.2",
+ "prettier": "^3.3.3",
"sinon": "^14.0.1",
"ts-node": "^10.9.2",
"tsc-watch": "^5.0.3",
"typescript": "^5.4.5",
+ "typescript-eslint": "^8.6.0",
"vinyl-buffer": "^1.0.1",
"vinyl-source-stream": "^2.0.0",
"xvfb-maybe": "^0.2.1"
@@ -86,7 +89,7 @@
"build-proto": "gulp build-proto",
"pack-test-executable": "./scripts/build-test-executable.sh",
"build-test-executable": "npm run build && npm run pack-test-executable",
- "lint": "eslint --ext tsx,ts .",
+ "lint": "eslint .",
"format": "prettier \"**/*.{js,css,ts,tsx}\" --write",
"tsc": "tsc -p . --noEmit",
"e2e": "npm run build && npm run e2e:no-build",
diff --git a/gui/prettier.config.mjs b/gui/prettier.config.mjs
new file mode 100644
index 0000000000..150678b825
--- /dev/null
+++ b/gui/prettier.config.mjs
@@ -0,0 +1,7 @@
+// see: https://prettier.io/docs/en/options.html
+export default {
+ printWidth: 100,
+ singleQuote: true,
+ bracketSameLine: true,
+ proseWrap: 'always',
+};
diff --git a/gui/scripts/extract-translations.js b/gui/scripts/extract-translations.js
index 30e04e298a..e101ca03a5 100644
--- a/gui/scripts/extract-translations.js
+++ b/gui/scripts/extract-translations.js
@@ -1,4 +1,4 @@
-const { GettextExtractor, JsExtractors, HtmlExtractors } = require('gettext-extractor');
+const { GettextExtractor, JsExtractors } = require('gettext-extractor');
const path = require('path');
const extractor = new GettextExtractor();
diff --git a/gui/scripts/verify-translations-format.ts b/gui/scripts/verify-translations-format.ts
index e44997d579..eaba3ee7b7 100644
--- a/gui/scripts/verify-translations-format.ts
+++ b/gui/scripts/verify-translations-format.ts
@@ -62,14 +62,14 @@ function checkFormatSpecifiers(translation: GetTextTranslation): boolean {
.every((result) => result);
}
-function checkHtmlTagsImpl(value: string): { correct: boolean, amount: number } {
- const tagsRegexp = new RegExp("<.*?>", "g");
+function checkHtmlTagsImpl(value: string): { correct: boolean; amount: number } {
+ const tagsRegexp = new RegExp('<.*?>', 'g');
const tags = value.match(tagsRegexp) ?? [];
const tagTypes = tags.map((tag) => tag.slice(1, -1));
// Make sure tags match by pushing start-tags to a stack and matching closing tags with the last
// item.
- let tagStack: string[] = [];
+ const tagStack: string[] = [];
for (let tag of tagTypes) {
const selfClosing = tag.endsWith('/');
const endTag = tag.startsWith('/');
@@ -94,21 +94,23 @@ function checkHtmlTagsImpl(value: string): { correct: boolean, amount: number }
}
if (tagStack.length > 0) {
- console.error(`Missing closing-tags (${tagStack}) in "${value}"`);
- return { correct: false, amount: NaN };
+ console.error(`Missing closing-tags (${tagStack}) in "${value}"`);
+ return { correct: false, amount: NaN };
}
return { correct: true, amount: tags.length / 2 };
}
function checkHtmlTags(translation: GetTextTranslation): boolean {
- let { correct, amount: sourceAmount } = checkHtmlTagsImpl(translation.msgid);
+ const { correct, amount: sourceAmount } = checkHtmlTagsImpl(translation.msgid);
- let translationsCorrect = translation.msgstr.every((value) => {
- let { correct, amount } = checkHtmlTagsImpl(value);
+ const translationsCorrect = translation.msgstr.every((value) => {
+ const { correct, amount } = checkHtmlTagsImpl(value);
// The amount doesn't make sense if the string isn't correctly formatted.
if (correct && amount !== sourceAmount) {
- console.error(`Incorrect amount of tags in translation for "${translation.msgid}": "${value}"`);
+ console.error(
+ `Incorrect amount of tags in translation for "${translation.msgid}": "${value}"`,
+ );
}
return correct && amount === sourceAmount;
});
diff --git a/gui/src/main/daemon-rpc.ts b/gui/src/main/daemon-rpc.ts
index 31f6ddcfab..1c96be12bb 100644
--- a/gui/src/main/daemon-rpc.ts
+++ b/gui/src/main/daemon-rpc.ts
@@ -791,7 +791,6 @@ export class DaemonRpc {
}
private channelOptions(): grpc.ClientOptions {
- /* eslint-disable @typescript-eslint/naming-convention */
return {
'grpc.max_reconnect_backoff_ms': 3000,
'grpc.initial_reconnect_backoff_ms': 3000,
@@ -799,7 +798,6 @@ export class DaemonRpc {
'grpc.keepalive_timeout_ms': Math.pow(2, 30),
'grpc.client_idle_timeout_ms': Math.pow(2, 30),
};
- /* eslint-enable @typescript-eslint/naming-convention */
}
private connectivityChangeCallback(timeoutErr?: Error) {
diff --git a/gui/src/main/index.ts b/gui/src/main/index.ts
index c5144ee99e..be6c6609a0 100644
--- a/gui/src/main/index.ts
+++ b/gui/src/main/index.ts
@@ -70,6 +70,7 @@ import Version, { GUI_VERSION } from './version';
const execAsync = util.promisify(exec);
// Only import split tunneling library on correct OS.
+// eslint-disable-next-line @typescript-eslint/no-require-imports
const linuxSplitTunneling = process.platform === 'linux' && require('./linux-split-tunneling');
// This is used on Windows and macOS and will be undefined on Linux.
const splitTunneling: ISplitTunnelingAppListRetriever | undefined = importSplitTunneling();
@@ -1115,11 +1116,11 @@ class ApplicationMain
function importSplitTunneling() {
if (process.platform === 'win32') {
- // eslint-disable-next-line @typescript-eslint/no-var-requires
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
const { WindowsSplitTunnelingAppListRetriever } = require('./windows-split-tunneling');
return new WindowsSplitTunnelingAppListRetriever();
} else if (process.platform === 'darwin') {
- // eslint-disable-next-line @typescript-eslint/no-var-requires
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
const { MacOsSplitTunnelingAppListRetriever } = require('./macos-split-tunneling');
return new MacOsSplitTunnelingAppListRetriever();
}
diff --git a/gui/src/main/linux-desktop-entry.ts b/gui/src/main/linux-desktop-entry.ts
index d6c11c7943..7cc46862a5 100644
--- a/gui/src/main/linux-desktop-entry.ts
+++ b/gui/src/main/linux-desktop-entry.ts
@@ -265,7 +265,6 @@ function getGtkThemeDirectories(): Promise<DirectoryDescription[]> {
process.env.ORIGINAL_XDG_CURRENT_DESKTOP ?? process.env.XDG_CURRENT_DESKTOP ?? '';
child_process.exec(
'gsettings get org.gnome.desktop.interface icon-theme',
- // eslint-disable-next-line @typescript-eslint/naming-convention
{ env: { XDG_CURRENT_DESKTOP: xdgCurrentDesktop } },
(error, stdout) => {
if (error) {
diff --git a/gui/src/main/linux-split-tunneling.ts b/gui/src/main/linux-split-tunneling.ts
index 3ae1a15390..6d690aa453 100644
--- a/gui/src/main/linux-split-tunneling.ts
+++ b/gui/src/main/linux-split-tunneling.ts
@@ -113,7 +113,7 @@ export async function getApplications(locale: string): Promise<ILinuxSplitTunnel
for (const entryPath of desktopEntryPaths) {
try {
desktopEntries.push(await readDesktopEntry(entryPath, locale));
- } catch (e) {
+ } catch {
// no-op
}
}
@@ -141,7 +141,7 @@ async function replaceIconNameWithDataUrl(
}
return { ...app, icon: await getImageDataUrl(iconPath) };
- } catch (e) {
+ } catch {
return app;
}
}
diff --git a/gui/src/main/logging.ts b/gui/src/main/logging.ts
index f71e3a62f0..a1942d5007 100644
--- a/gui/src/main/logging.ts
+++ b/gui/src/main/logging.ts
@@ -113,7 +113,7 @@ function fileExists(filePath: string): boolean {
try {
fs.accessSync(filePath);
return true;
- } catch (e) {
+ } catch {
return false;
}
}
diff --git a/gui/src/main/user-interface.ts b/gui/src/main/user-interface.ts
index a0b4662c48..f7b81247ff 100644
--- a/gui/src/main/user-interface.ts
+++ b/gui/src/main/user-interface.ts
@@ -494,7 +494,7 @@ export default class UserInterface implements WindowControllerDelegate {
return;
}
- // eslint-disable-next-line @typescript-eslint/no-var-requires
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
const { NSEventMonitor, NSEventMask } = require('nseventmonitor');
const macEventMonitor = new NSEventMonitor();
const eventMask = NSEventMask.leftMouseDown | NSEventMask.rightMouseDown;
diff --git a/gui/src/main/windows-split-tunneling.ts b/gui/src/main/windows-split-tunneling.ts
index 5ba594f7cc..7ae73827d0 100644
--- a/gui/src/main/windows-split-tunneling.ts
+++ b/gui/src/main/windows-split-tunneling.ts
@@ -288,7 +288,7 @@ export class WindowsSplitTunnelingAppListRetriever implements ISplitTunnelingApp
let fileHandle: fs.promises.FileHandle;
try {
fileHandle = await fs.promises.open(path, fs.constants.O_RDONLY);
- } catch (e) {
+ } catch {
return false;
}
diff --git a/gui/src/renderer/app.tsx b/gui/src/renderer/app.tsx
index a4d5fc2fad..c961d07258 100644
--- a/gui/src/renderer/app.tsx
+++ b/gui/src/renderer/app.tsx
@@ -400,7 +400,7 @@ export default class AppRenderer {
this.loginState = 'too many devices';
this.history.reset(RoutePath.tooManyDevices, { transition: transitions.push });
- } catch (e) {
+ } catch {
log.error('Failed to fetch device list');
actions.account.loginFailed('list-devices');
}
diff --git a/gui/src/renderer/components/ClipboardLabel.tsx b/gui/src/renderer/components/ClipboardLabel.tsx
index 582e03b02d..e9f760fd07 100644
--- a/gui/src/renderer/components/ClipboardLabel.tsx
+++ b/gui/src/renderer/components/ClipboardLabel.tsx
@@ -62,7 +62,7 @@ export default function ClipboardLabel(props: IProps) {
return (
<StyledLabelContainer>
<StyledLabel aria-hidden={obscured} {...otherProps}>
- {obscured ? '●●●● ●●●● ●●●● ●●●●' : displayValue ?? value}
+ {obscured ? '●●●● ●●●● ●●●● ●●●●' : (displayValue ?? value)}
</StyledLabel>
{obscureValue !== false && (
<StyledButton
diff --git a/gui/src/renderer/components/EditApiAccessMethod.tsx b/gui/src/renderer/components/EditApiAccessMethod.tsx
index 97996d7f42..a8602675a0 100644
--- a/gui/src/renderer/components/EditApiAccessMethod.tsx
+++ b/gui/src/renderer/components/EditApiAccessMethod.tsx
@@ -62,7 +62,7 @@ function AccessMethodForm() {
const onSave = useCallback(
async (newMethod: NamedCustomProxy) => {
- const enabled = id === undefined ? true : method?.enabled ?? true;
+ const enabled = id === undefined ? true : (method?.enabled ?? true);
updatedMethod.current = { ...newMethod, enabled };
if (
updatedMethod.current !== undefined &&
diff --git a/gui/src/renderer/components/ImageView.tsx b/gui/src/renderer/components/ImageView.tsx
index fa3855b21a..f40a93fbbc 100644
--- a/gui/src/renderer/components/ImageView.tsx
+++ b/gui/src/renderer/components/ImageView.tsx
@@ -46,7 +46,6 @@ export default function ImageView(props: IImageViewProps) {
? props.source
: `../../assets/images/${props.source}.svg`;
- // eslint-disable-next-line @typescript-eslint/naming-convention
const style = useMemo(() => ({ WebkitMaskImage: `url('${url}')` }), [url]);
if (props.tintColor) {
diff --git a/gui/src/renderer/components/Login.tsx b/gui/src/renderer/components/Login.tsx
index 32eb5bbe82..e5f981eafb 100644
--- a/gui/src/renderer/components/Login.tsx
+++ b/gui/src/renderer/components/Login.tsx
@@ -281,7 +281,7 @@ export default class Login extends React.Component<IProps, IState> {
await this.props.clearAccountHistory();
// TODO: Remove account from memory
- } catch (error) {
+ } catch {
// TODO: Show error
}
}
diff --git a/gui/src/renderer/components/NotificationBanner.tsx b/gui/src/renderer/components/NotificationBanner.tsx
index ad84ad3697..f79855f004 100644
--- a/gui/src/renderer/components/NotificationBanner.tsx
+++ b/gui/src/renderer/components/NotificationBanner.tsx
@@ -167,7 +167,7 @@ export function NotificationBanner(props: INotificationBannerProps) {
useEffect(() => {
const newHeight =
- props.children !== undefined ? contentRef.current?.getBoundingClientRect().height ?? 0 : 0;
+ props.children !== undefined ? (contentRef.current?.getBoundingClientRect().height ?? 0) : 0;
if (newHeight !== contentHeight) {
setContentHeight(newHeight);
setAlignBottom((alignBottom) => alignBottom || contentHeight === 0 || newHeight === 0);
diff --git a/gui/src/renderer/components/ProblemReport.tsx b/gui/src/renderer/components/ProblemReport.tsx
index 3a0a9bbd0e..fd481cde07 100644
--- a/gui/src/renderer/components/ProblemReport.tsx
+++ b/gui/src/renderer/components/ProblemReport.tsx
@@ -137,7 +137,7 @@ function Form() {
try {
const reportId = await collectLog();
await viewLog(reportId);
- } catch (error) {
+ } catch {
// TODO: handle error
} finally {
setDisableActions(false);
@@ -431,7 +431,7 @@ const ProblemReportContextProvider = ({ children }: { children: ReactNode }) =>
await sendProblemReport(email, message, reportId);
clearReportForm();
setSendState(SendState.success);
- } catch (error) {
+ } catch {
setSendState(SendState.failed);
}
}, [email, message]);
@@ -447,7 +447,7 @@ const ProblemReportContextProvider = ({ children }: { children: ReactNode }) =>
try {
setSendState(SendState.sending);
await sendReport();
- } catch (error) {
+ } catch {
// No-op
}
}
diff --git a/gui/src/renderer/components/main-view/FeatureIndicators.tsx b/gui/src/renderer/components/main-view/FeatureIndicators.tsx
index 1696a6fd20..a4bf8659c6 100644
--- a/gui/src/renderer/components/main-view/FeatureIndicators.tsx
+++ b/gui/src/renderer/components/main-view/FeatureIndicators.tsx
@@ -116,7 +116,7 @@ export default function FeatureIndicators(props: FeatureIndicatorsProps) {
tunnelState.state === 'connected' || tunnelState.state === 'connecting';
const featureIndicators = useRef(
- featureIndicatorsVisible ? tunnelState.featureIndicators ?? [] : [],
+ featureIndicatorsVisible ? (tunnelState.featureIndicators ?? []) : [],
);
if (featureIndicatorsVisible && tunnelState.featureIndicators) {
diff --git a/gui/src/renderer/lib/ip.ts b/gui/src/renderer/lib/ip.ts
index 94eb807d49..db458aa256 100644
--- a/gui/src/renderer/lib/ip.ts
+++ b/gui/src/renderer/lib/ip.ts
@@ -15,7 +15,7 @@ export abstract class IpAddress<G extends number[]> {
public static fromString(ip: string): IPv4Address | IPv6Address {
try {
return IPv4Address.fromString(ip);
- } catch (e) {
+ } catch {
return IPv6Address.fromString(ip);
}
}
@@ -80,7 +80,7 @@ export class IPv4Address extends IpAddress<IPv4Octets> {
try {
const octets = IPv4Address.octetsFromString(ip);
return new IPv4Address(octets);
- } catch (e) {
+ } catch {
throw new Error(`Invalid ip: ${ip}`);
}
}
@@ -94,7 +94,7 @@ export class IPv4Address extends IpAddress<IPv4Octets> {
return parsedOctets;
}
}
- } catch (e) {
+ } catch {
// no-op
}
@@ -105,7 +105,7 @@ export class IPv4Address extends IpAddress<IPv4Octets> {
try {
IPv4Address.fromString(ip);
return true;
- } catch (e) {
+ } catch {
return false;
}
}
@@ -135,7 +135,7 @@ export class IPv4Range extends IpRange<IPv4Octets> {
const prefixSize = parseInt(parts[1]);
return new IPv4Range(octets, prefixSize);
}
- } catch (e) {
+ } catch {
// no-op
}
@@ -167,7 +167,7 @@ export class IPv6Address extends IpAddress<IPv6Groups> {
try {
const groups = IPv6Address.groupsFromString(ip);
return new IPv6Address(groups);
- } catch (e) {
+ } catch {
throw new Error(`Invalid ip: ${ip}`);
}
}
@@ -200,7 +200,7 @@ export class IPv6Address extends IpAddress<IPv6Groups> {
}
}
}
- } catch (e) {
+ } catch {
// no-op
}
@@ -211,7 +211,7 @@ export class IPv6Address extends IpAddress<IPv6Groups> {
try {
IPv6Address.fromString(ip);
return true;
- } catch (e) {
+ } catch {
return false;
}
}
@@ -241,7 +241,7 @@ export class IPv6Range extends IpRange<IPv6Groups> {
const prefixSize = parseInt(parts[1], 10);
return new IPv6Range(groups, prefixSize);
}
- } catch (e) {
+ } catch {
// no-op
}
diff --git a/gui/tasks/assets.js b/gui/tasks/assets.js
index 56b0c7a8ad..8028124180 100644
--- a/gui/tasks/assets.js
+++ b/gui/tasks/assets.js
@@ -31,7 +31,14 @@ copyHtml.displayName = 'copy-html';
copyLocales.displayName = 'copy-locales';
copyGeoData.displayName = 'copy-geo-data';
-exports.copyAll = parallel(copyStaticAssets, copyConfig, copyCss, copyHtml, copyLocales, copyGeoData);
+exports.copyAll = parallel(
+ copyStaticAssets,
+ copyConfig,
+ copyCss,
+ copyHtml,
+ copyLocales,
+ copyGeoData,
+);
exports.copyStaticAssets = copyStaticAssets;
exports.copyCss = copyCss;
exports.copyHtml = copyHtml;
diff --git a/gui/tasks/distribution.js b/gui/tasks/distribution.js
index a7f7c29d6d..0e80c3c73f 100644
--- a/gui/tasks/distribution.js
+++ b/gui/tasks/distribution.js
@@ -42,7 +42,7 @@ const config = {
name: 'mullvad-vpn',
// We have to stick to semver on Windows for now due to:
// https://github.com/electron-userland/electron-builder/issues/7173
- version: productVersion(process.platform === 'win32' ? ['semver'] : [])
+ version: productVersion(process.platform === 'win32' ? ['semver'] : []),
},
files: [
@@ -139,23 +139,44 @@ const config = {
publisherName: 'Mullvad VPN AB',
extraResources: [
{ from: distAssets(path.join(getWindowsDistSubdir(), 'mullvad.exe')), to: '.' },
- { from: distAssets(path.join(getWindowsDistSubdir(), 'mullvad-problem-report.exe')), to: '.' },
+ {
+ from: distAssets(path.join(getWindowsDistSubdir(), 'mullvad-problem-report.exe')),
+ to: '.',
+ },
{ from: distAssets(path.join(getWindowsDistSubdir(), 'mullvad-daemon.exe')), to: '.' },
{ from: distAssets(path.join(getWindowsDistSubdir(), 'talpid_openvpn_plugin.dll')), to: '.' },
{
- from: root(path.join('windows', 'winfw', 'bin', getWindowsTargetArch() + '-${env.CPP_BUILD_MODE}', 'winfw.dll')),
+ from: root(
+ path.join(
+ 'windows',
+ 'winfw',
+ 'bin',
+ getWindowsTargetArch() + '-${env.CPP_BUILD_MODE}',
+ 'winfw.dll',
+ ),
+ ),
to: '.',
},
// TODO: OpenVPN does not have an ARM64 build yet.
{ from: distAssets('binaries/x86_64-pc-windows-msvc/openvpn.exe'), to: '.' },
- { from: distAssets(path.join('binaries', getWindowsTargetSubdir(), 'apisocks5.exe')), to: '.' },
- { from: distAssets(path.join('binaries', getWindowsTargetSubdir(), 'wintun/wintun.dll')), to: '.' },
{
- from: distAssets(path.join('binaries', getWindowsTargetSubdir(), 'split-tunnel/mullvad-split-tunnel.sys')),
- to: '.'
+ from: distAssets(path.join('binaries', getWindowsTargetSubdir(), 'apisocks5.exe')),
+ to: '.',
+ },
+ {
+ from: distAssets(path.join('binaries', getWindowsTargetSubdir(), 'wintun/wintun.dll')),
+ to: '.',
+ },
+ {
+ from: distAssets(
+ path.join('binaries', getWindowsTargetSubdir(), 'split-tunnel/mullvad-split-tunnel.sys'),
+ ),
+ to: '.',
},
{
- from: distAssets(path.join('binaries', getWindowsTargetSubdir(), 'wireguard-nt/mullvad-wireguard.dll')),
+ from: distAssets(
+ path.join('binaries', getWindowsTargetSubdir(), 'wireguard-nt/mullvad-wireguard.dll'),
+ ),
to: '.',
},
{ from: distAssets('maybenot_machines'), to: '.' },
@@ -180,7 +201,10 @@ const config = {
extraResources: [
{ from: distAssets(path.join(getLinuxTargetSubdir(), 'mullvad-problem-report')), to: '.' },
{ from: distAssets(path.join(getLinuxTargetSubdir(), 'mullvad-setup')), to: '.' },
- { from: distAssets(path.join(getLinuxTargetSubdir(), 'libtalpid_openvpn_plugin.so')), to: '.' },
+ {
+ from: distAssets(path.join(getLinuxTargetSubdir(), 'libtalpid_openvpn_plugin.so')),
+ to: '.',
+ },
{ from: distAssets(path.join('linux', 'apparmor_mullvad')), to: '.' },
{ from: distAssets(path.join('binaries', '${env.TARGET_TRIPLE}', 'openvpn')), to: '.' },
{ from: distAssets(path.join('binaries', '${env.TARGET_TRIPLE}', 'apisocks5')), to: '.' },
@@ -197,8 +221,10 @@ const config = {
distAssets('linux/before-install.sh'),
'--before-remove',
distAssets('linux/before-remove.sh'),
- distAssets('linux/mullvad-daemon.service') +'=/usr/lib/systemd/system/mullvad-daemon.service',
- distAssets('linux/mullvad-early-boot-blocking.service') +'=/usr/lib/systemd/system/mullvad-early-boot-blocking.service',
+ distAssets('linux/mullvad-daemon.service') +
+ '=/usr/lib/systemd/system/mullvad-daemon.service',
+ distAssets('linux/mullvad-early-boot-blocking.service') +
+ '=/usr/lib/systemd/system/mullvad-early-boot-blocking.service',
distAssets(path.join(getLinuxTargetSubdir(), 'mullvad')) + '=/usr/bin/',
distAssets(path.join(getLinuxTargetSubdir(), 'mullvad-daemon')) + '=/usr/bin/',
distAssets(path.join(getLinuxTargetSubdir(), 'mullvad-exclude')) + '=/usr/bin/',
@@ -228,8 +254,10 @@ const config = {
distAssets('linux/before-remove.sh'),
'--rpm-posttrans',
distAssets('linux/post-transaction.sh'),
- distAssets('linux/mullvad-daemon.service') +'=/usr/lib/systemd/system/mullvad-daemon.service',
- distAssets('linux/mullvad-early-boot-blocking.service') +'=/usr/lib/systemd/system/mullvad-early-boot-blocking.service',
+ distAssets('linux/mullvad-daemon.service') +
+ '=/usr/lib/systemd/system/mullvad-daemon.service',
+ distAssets('linux/mullvad-early-boot-blocking.service') +
+ '=/usr/lib/systemd/system/mullvad-early-boot-blocking.service',
distAssets(path.join(getLinuxTargetSubdir(), 'mullvad')) + '=/usr/bin/',
distAssets(path.join(getLinuxTargetSubdir(), 'mullvad-daemon')) + '=/usr/bin/',
distAssets(path.join(getLinuxTargetSubdir(), 'mullvad-exclude')) + '=/usr/bin/',
@@ -265,7 +293,7 @@ function packWin() {
process.env.SETUP_SUBDIR = 'aarch64-pc-windows-msvc';
break;
default:
- throw new Error(`Invalid or unknown target (only one may be specified)`);
+ throw new Error('Invalid or unknown target (only one may be specified)');
}
return true;
},
@@ -279,9 +307,12 @@ function packWin() {
for (const artifactPath of buildResult.artifactPaths) {
const artifactDir = path.dirname(artifactPath);
const artifactSemverFilename = path.basename(artifactPath);
- const artifactDesiredFilename = artifactSemverFilename.replace(productSemverVersion, productTargetVersion);
+ const artifactDesiredFilename = artifactSemverFilename.replace(
+ productSemverVersion,
+ productTargetVersion,
+ );
const targetArtifactPath = path.join(artifactDir, artifactDesiredFilename);
- console.log("Moving", artifactSemverFilename, "=>", artifactDesiredFilename);
+ console.log('Moving', artifactSemverFilename, '=>', artifactDesiredFilename);
fs.renameSync(artifactPath, targetArtifactPath);
}
},
@@ -310,9 +341,8 @@ function packMac() {
break;
}
- process.env.BINARIES_PATH = hostTargetTriple !== process.env.TARGET_TRIPLE
- ? process.env.TARGET_TRIPLE
- : '';
+ process.env.BINARIES_PATH =
+ hostTargetTriple !== process.env.TARGET_TRIPLE ? process.env.TARGET_TRIPLE : '';
return true;
},
@@ -322,8 +352,12 @@ function packMac() {
// if they're present for both targets. So make sure we remove libraries for other archs.
// Remove the workaround once the issue has been fixed:
// https://github.com/electron/universal/issues/41#issuecomment-1496288834
- await fs.promises.rm('node_modules/nseventmonitor/lib/binding/Release', { recursive: true });
- } catch {}
+ await fs.promises.rm('node_modules/nseventmonitor/lib/binding/Release', {
+ recursive: true,
+ });
+ } catch {
+ // noop
+ }
config.beforePack?.(context);
},
afterPack: (context) => {
@@ -336,13 +370,15 @@ function packMac() {
return Promise.resolve();
},
- afterAllArtifactBuild: async (buildResult) => {
+ afterAllArtifactBuild: async (_buildResult) => {
// Remove the folder that contains the unpacked app. Electron builder cleans up some of
// these directories and it's changed between versions without a mention in the changelog.
for (const dir of appOutDirs) {
try {
await fs.promises.rm(dir, { recursive: true });
- } catch {}
+ } catch {
+ // noop
+ }
}
},
afterSign: (context) => {
@@ -359,7 +395,7 @@ function packLinux() {
}
if (targets && targets === 'aarch64-unknown-linux-gnu') {
- config.rpm.fpm.unshift('--architecture', 'aarch64')
+ config.rpm.fpm.unshift('--architecture', 'aarch64');
}
return builder.build({
@@ -422,7 +458,7 @@ function getWindowsTargetArch() {
if (targets === 'aarch64-pc-windows-msvc') {
return 'arm64';
}
- throw new Error(`Invalid or unknown target (only one may be specified)`);
+ throw new Error('Invalid or unknown target (only one may be specified)');
}
// Use host architecture (we assume this is x64 since building on Arm64 isn't supported).
return 'x64';
@@ -433,7 +469,7 @@ function getWindowsTargetSubdir() {
if (targets === 'aarch64-pc-windows-msvc') {
return targets;
}
- throw new Error(`Invalid or unknown target (only one may be specified)`);
+ throw new Error('Invalid or unknown target (only one may be specified)');
}
// Use host architecture (we assume this is x64 since building on Arm64 isn't supported).
return 'x86_64-pc-windows-msvc';
@@ -444,7 +480,7 @@ function getLinuxTargetArch() {
if (targets === 'aarch64-unknown-linux-gnu') {
return 'arm64';
}
- throw new Error(`Invalid or unknown target (only one may be specified)`);
+ throw new Error('Invalid or unknown target (only one may be specified)');
}
// Use host architecture.
return undefined;
@@ -455,7 +491,7 @@ function getLinuxTargetSubdir() {
if (targets === 'aarch64-unknown-linux-gnu') {
return targets;
}
- throw new Error(`Invalid or unknown target (only one may be specified)`);
+ throw new Error('Invalid or unknown target (only one may be specified)');
}
return '';
}
@@ -489,8 +525,8 @@ function getLinuxVersion() {
// Returns the product version. The `args` argument is optional. Set it to `'semver'`
// to get the version in semver format.
-function productVersion(extra_args) {
- const args = ['run', '-q', '--bin', 'mullvad-version', ...extra_args];
+function productVersion(extraArgs) {
+ const args = ['run', '-q', '--bin', 'mullvad-version', ...extraArgs];
return execFileSync('cargo', args, { encoding: 'utf-8' }).trim();
}
diff --git a/gui/tasks/scripts.js b/gui/tasks/scripts.js
index 36b9def82d..20acc69c35 100644
--- a/gui/tasks/scripts.js
+++ b/gui/tasks/scripts.js
@@ -37,7 +37,9 @@ function makeWatchCompiler(onFirstSuccess, onSuccess) {
) {
lastBundle = bundle;
lastPreloadBundle = preloadBundle;
- !wasFirstBuild && onSuccess();
+ if (!wasFirstBuild) {
+ onSuccess();
+ }
}
}),
);
diff --git a/gui/test/e2e/installed/installed-utils.ts b/gui/test/e2e/installed/installed-utils.ts
index 1a8cd4258e..9e4dd6c79c 100644
--- a/gui/test/e2e/installed/installed-utils.ts
+++ b/gui/test/e2e/installed/installed-utils.ts
@@ -2,7 +2,7 @@ import { startApp } from '../utils';
export const startInstalledApp = async (): ReturnType<typeof startApp> => {
return startApp({ executablePath: getAppInstallPath() });
-}
+};
function getAppInstallPath(): string {
switch (process.platform) {
diff --git a/gui/test/e2e/installed/playwright.config.ts b/gui/test/e2e/installed/playwright.config.ts
index 9c1fa7fb87..9487e06905 100644
--- a/gui/test/e2e/installed/playwright.config.ts
+++ b/gui/test/e2e/installed/playwright.config.ts
@@ -1,4 +1,4 @@
-import { defineConfig } from "@playwright/test";
+import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: process.cwd(),
diff --git a/gui/test/e2e/installed/state-dependent/api-access-methods.spec.ts b/gui/test/e2e/installed/state-dependent/api-access-methods.spec.ts
index 0d6e8a0672..d17611261b 100644
--- a/gui/test/e2e/installed/state-dependent/api-access-methods.spec.ts
+++ b/gui/test/e2e/installed/state-dependent/api-access-methods.spec.ts
@@ -1,9 +1,9 @@
import { expect, test } from '@playwright/test';
import { Page } from 'playwright';
-import { startInstalledApp } from '../installed-utils';
-import { TestUtils } from '../../utils';
import { RoutePath } from '../../../../src/renderer/lib/routes';
+import { TestUtils } from '../../utils';
+import { startInstalledApp } from '../installed-utils';
// This test expects the daemon to be logged in and only have "Direct" and "Mullvad Bridges"
// access methods.
@@ -31,10 +31,10 @@ test.afterAll(async () => {
});
async function navigateToAccessMethods() {
- await util.waitForNavigation(async () => await page.click('button[aria-label="Settings"]'));
- await util.waitForNavigation(async () => await page.getByText('API access').click());
+ await util.waitForNavigation(() => page.click('button[aria-label="Settings"]'));
+ await util.waitForNavigation(() => page.getByText('API access').click());
- const title = page.locator('h1')
+ const title = page.locator('h1');
await expect(title).toHaveText('API access');
}
@@ -52,9 +52,9 @@ test('App should display access methods', async () => {
});
test('App should add invalid access method', async () => {
- await util.waitForNavigation(async () => await page.locator('button:has-text("Add")').click());
+ await util.waitForNavigation(() => page.locator('button:has-text("Add")').click());
- const title = page.locator('h1')
+ const title = page.locator('h1');
await expect(title).toHaveText('Add method');
const inputs = page.locator('input');
@@ -71,13 +71,13 @@ test('App should add invalid access method', async () => {
await inputs.nth(2).fill(process.env.SHADOWSOCKS_SERVER_PORT!);
await expect(addButton).toBeEnabled();
- await addButton.click()
+ await addButton.click();
await expect(page.getByText('Testing method...')).toBeVisible();
await expect(page.getByText('API unreachable, add anyway?')).toBeVisible();
expect(
- await util.waitForNavigation(async () => await page.locator('button:has-text("Save")').click())
+ await util.waitForNavigation(() => page.locator('button:has-text("Save")').click()),
).toEqual(RoutePath.apiAccessMethods);
const accessMethods = page.getByTestId('access-method');
@@ -107,7 +107,7 @@ test('App should edit access method', async () => {
await customMethod.locator('button').last().click();
await util.waitForNavigation(() => customMethod.getByText('Edit').click());
- const title = page.locator('h1')
+ const title = page.locator('h1');
await expect(title).toHaveText('Edit method');
const inputs = page.locator('input');
@@ -125,11 +125,13 @@ test('App should edit access method', async () => {
await inputs.nth(3).fill(process.env.SHADOWSOCKS_SERVER_PASSWORD!);
await page.getByTestId('ciphers').click();
- await page.getByRole('option', { name: process.env.SHADOWSOCKS_SERVER_CIPHER!, exact: true }).click();
+ await page
+ .getByRole('option', { name: process.env.SHADOWSOCKS_SERVER_CIPHER!, exact: true })
+ .click();
- expect(
- await util.waitForNavigation(async () => await saveButton.click())
- ).toEqual(RoutePath.apiAccessMethods);
+ expect(await util.waitForNavigation(() => saveButton.click())).toEqual(
+ RoutePath.apiAccessMethods,
+ );
const accessMethods = page.getByTestId('access-method');
await expect(accessMethods).toHaveCount(3);
diff --git a/gui/test/e2e/installed/state-dependent/custom-bridge.spec.ts b/gui/test/e2e/installed/state-dependent/custom-bridge.spec.ts
index 5efd110213..34efb60f26 100644
--- a/gui/test/e2e/installed/state-dependent/custom-bridge.spec.ts
+++ b/gui/test/e2e/installed/state-dependent/custom-bridge.spec.ts
@@ -1,10 +1,10 @@
import { expect, test } from '@playwright/test';
import { Page } from 'playwright';
-import { startInstalledApp } from '../installed-utils';
-import { TestUtils } from '../../utils';
import { colors } from '../../../../src/config.json';
import { RoutePath } from '../../../../src/renderer/lib/routes';
+import { TestUtils } from '../../utils';
+import { startInstalledApp } from '../installed-utils';
// This test expects the daemon to be logged in and not have a custom bridge configured.
// Env parameters:
@@ -25,37 +25,35 @@ test.afterAll(async () => {
});
test('App should enable bridge mode', async () => {
- await util.waitForNavigation(async () => await page.click('button[aria-label="Settings"]'));
- expect(
- await util.waitForNavigation(async () => await page.getByText('VPN settings').click()),
- ).toBe(RoutePath.vpnSettings);
+ await util.waitForNavigation(() => page.click('button[aria-label="Settings"]'));
+ expect(await util.waitForNavigation(() => page.getByText('VPN settings').click())).toBe(
+ RoutePath.vpnSettings,
+ );
await page.getByRole('option', { name: 'OpenVPN' }).click();
- expect(
- await util.waitForNavigation(async () => await page.getByText('OpenVPN settings').click()),
- ).toBe(RoutePath.openVpnSettings);
+ expect(await util.waitForNavigation(() => page.getByText('OpenVPN settings').click())).toBe(
+ RoutePath.openVpnSettings,
+ );
await page.getByTestId('bridge-mode-on').click();
await expect(page.getByText('Enable bridge mode?')).toBeVisible();
- page.getByTestId('enable-confirm').click();
+ await page.getByTestId('enable-confirm').click();
- await util.waitForNavigation(async () => await page.click('button[aria-label="Back"]'));
- await util.waitForNavigation(async () => await page.click('button[aria-label="Back"]'));
- expect(
- await util.waitForNavigation(async () => await page.click('button[aria-label="Close"]')),
- ).toBe(RoutePath.main);
+ await util.waitForNavigation(() => page.click('button[aria-label="Back"]'));
+ await util.waitForNavigation(() => page.click('button[aria-label="Back"]'));
+ expect(await util.waitForNavigation(() => page.click('button[aria-label="Close"]'))).toBe(
+ RoutePath.main,
+ );
});
test('App display disabled custom bridge', async () => {
expect(
- await util.waitForNavigation(
- async () => await page.click('button[aria-label^="Select location"]'),
- ),
+ await util.waitForNavigation(() => page.click('button[aria-label^="Select location"]')),
).toBe(RoutePath.selectLocation);
- const title = page.locator('h1')
+ const title = page.locator('h1');
await expect(title).toHaveText('Select location');
await page.getByText(/^Entry$/).click();
@@ -66,12 +64,10 @@ test('App display disabled custom bridge', async () => {
test('App should add new custom bridge', async () => {
expect(
- await util.waitForNavigation(
- async () => await page.click('button[aria-label="Add new custom bridge"]'),
- ),
+ await util.waitForNavigation(() => page.click('button[aria-label="Add new custom bridge"]')),
).toBe(RoutePath.editCustomBridge);
- const title = page.locator('h1')
+ const title = page.locator('h1');
await expect(title).toHaveText('Add custom bridge');
const inputs = page.locator('input');
@@ -88,11 +84,11 @@ test('App should add new custom bridge', async () => {
await inputs.nth(2).fill(process.env.SHADOWSOCKS_SERVER_PASSWORD!);
await page.getByTestId('ciphers').click();
- await page.getByRole('option', { name: process.env.SHADOWSOCKS_SERVER_CIPHER!, exact: true }).click();
+ await page
+ .getByRole('option', { name: process.env.SHADOWSOCKS_SERVER_CIPHER!, exact: true })
+ .click();
- expect(
- await util.waitForNavigation(async () => await addButton.click())
- ).toEqual(RoutePath.selectLocation);
+ expect(await util.waitForNavigation(() => addButton.click())).toEqual(RoutePath.selectLocation);
const customBridgeButton = page.getByText('Custom bridge');
await expect(customBridgeButton).toBeEnabled();
@@ -109,11 +105,9 @@ test('App should select custom bridge', async () => {
await page.getByText(/^Entry$/).click();
await expect(customBridgeButton).not.toHaveCSS('background-color', colors.green);
-
await customBridgeButton.click();
await page.getByText(/^Entry$/).click();
await expect(customBridgeButton).toHaveCSS('background-color', colors.green);
-
});
test('App should edit custom bridge', async () => {
@@ -122,12 +116,10 @@ test('App should edit custom bridge', async () => {
await page.getByText(/^Entry$/).click();
expect(
- await util.waitForNavigation(
- async () => await page.click('button[aria-label="Edit custom bridge"]'),
- ),
+ await util.waitForNavigation(() => page.click('button[aria-label="Edit custom bridge"]')),
).toBe(RoutePath.editCustomBridge);
- const title = page.locator('h1')
+ const title = page.locator('h1');
await expect(title).toHaveText('Edit custom bridge');
const inputs = page.locator('input');
@@ -138,10 +130,7 @@ test('App should edit custom bridge', async () => {
await inputs.nth(1).fill(process.env.SHADOWSOCKS_SERVER_PORT!);
await expect(saveButton).toBeEnabled();
-
- expect(
- await util.waitForNavigation(async () => await saveButton.click())
- ).toEqual(RoutePath.selectLocation);
+ expect(await util.waitForNavigation(() => saveButton.click())).toEqual(RoutePath.selectLocation);
const customBridgeButton = page.locator('button:has-text("Custom bridge")');
await expect(customBridgeButton).toBeEnabled();
@@ -150,9 +139,7 @@ test('App should edit custom bridge', async () => {
test('App should delete custom bridge', async () => {
expect(
- await util.waitForNavigation(
- async () => await page.click('button[aria-label="Edit custom bridge"]'),
- ),
+ await util.waitForNavigation(() => page.click('button[aria-label="Edit custom bridge"]')),
).toBe(RoutePath.editCustomBridge);
const deleteButton = page.locator('button:has-text("Delete")');
@@ -163,9 +150,9 @@ test('App should delete custom bridge', async () => {
await expect(page.getByText('Delete custom bridge?')).toBeVisible();
const confirmButton = page.getByTestId('delete-confirm');
- expect(
- await util.waitForNavigation(async () => await confirmButton.click())
- ).toEqual(RoutePath.selectLocation);
+ expect(await util.waitForNavigation(() => confirmButton.click())).toEqual(
+ RoutePath.selectLocation,
+ );
const customBridgeButton = page.locator('button:has-text("Custom bridge")');
await expect(customBridgeButton).toBeDisabled();
diff --git a/gui/test/e2e/installed/state-dependent/device-revoked.spec.ts b/gui/test/e2e/installed/state-dependent/device-revoked.spec.ts
index 22aa30b3d5..2b9f8d0c58 100644
--- a/gui/test/e2e/installed/state-dependent/device-revoked.spec.ts
+++ b/gui/test/e2e/installed/state-dependent/device-revoked.spec.ts
@@ -1,8 +1,8 @@
import { expect, test } from '@playwright/test';
import { Page } from 'playwright';
+
import { RoutePath } from '../../../../src/renderer/lib/routes';
import { TestUtils } from '../../utils';
-
import { startInstalledApp } from '../installed-utils';
// This test expects the daemon to be logged in to a revoked device.
@@ -23,7 +23,7 @@ test('App should fail to login', async () => {
await expect(page.getByTestId('title')).toHaveText('Device is inactive');
- expect(await util.waitForNavigation(() => {
- page.getByText('Go to login').click();
- })).toEqual(RoutePath.login);
+ expect(await util.waitForNavigation(() => page.getByText('Go to login').click())).toEqual(
+ RoutePath.login,
+ );
});
diff --git a/gui/test/e2e/installed/state-dependent/disconnected.spec.ts b/gui/test/e2e/installed/state-dependent/disconnected.spec.ts
index 360a88338d..253545dad7 100644
--- a/gui/test/e2e/installed/state-dependent/disconnected.spec.ts
+++ b/gui/test/e2e/installed/state-dependent/disconnected.spec.ts
@@ -1,7 +1,7 @@
import { test } from '@playwright/test';
import { Page } from 'playwright';
-import { expectDisconnected } from '../../shared/tunnel-state';
+import { expectDisconnected } from '../../shared/tunnel-state';
import { startInstalledApp } from '../installed-utils';
// This test expects the daemon to be logged into an account that has time left and to be
diff --git a/gui/test/e2e/installed/state-dependent/location.spec.ts b/gui/test/e2e/installed/state-dependent/location.spec.ts
index 229adb9acc..f0bd2e11f7 100644
--- a/gui/test/e2e/installed/state-dependent/location.spec.ts
+++ b/gui/test/e2e/installed/state-dependent/location.spec.ts
@@ -20,7 +20,6 @@ test('App should have a country', async () => {
await expect(countryLabel).not.toBeEmpty();
const cityLabel = page.getByTestId('city');
- const noCityLabel = await cityLabel.count() === 0;
+ const noCityLabel = (await cityLabel.count()) === 0;
expect(noCityLabel).toBeTruthy();
});
-
diff --git a/gui/test/e2e/installed/state-dependent/login.spec.ts b/gui/test/e2e/installed/state-dependent/login.spec.ts
index ba72a5b466..ad49c88edd 100644
--- a/gui/test/e2e/installed/state-dependent/login.spec.ts
+++ b/gui/test/e2e/installed/state-dependent/login.spec.ts
@@ -1,11 +1,11 @@
-import { exec, execSync } from 'child_process';
import { expect, test } from '@playwright/test';
+import { exec, execSync } from 'child_process';
import { Locator, Page } from 'playwright';
+
import { RoutePath } from '../../../../src/renderer/lib/routes';
+import { expectDisconnected } from '../../shared/tunnel-state';
import { TestUtils } from '../../utils';
-
import { startInstalledApp } from '../installed-utils';
-import { expectDisconnected } from '../../shared/tunnel-state';
// This test expects the daemon to be logged out.
// Env parameters:
@@ -27,7 +27,7 @@ test.afterAll(async () => {
test('App should fail to login', async () => {
expect(await util.currentRoute()).toEqual(RoutePath.login);
- const title = page.locator('h1')
+ const title = page.locator('h1');
const subtitle = page.getByTestId('subtitle');
const loginInput = getInput(page);
@@ -46,15 +46,17 @@ test('App should fail to login', async () => {
test('App should create account', async () => {
expect(await util.currentRoute()).toEqual(RoutePath.login);
- const title = page.locator('h1')
+ const title = page.locator('h1');
const subtitle = page.getByTestId('subtitle');
- expect(await util.waitForNavigation(async () => {
- await page.getByText('Create account').click();
+ expect(
+ await util.waitForNavigation(async () => {
+ await page.getByText('Create account').click();
- await expect(title).toHaveText('Account created');
- await expect(subtitle).toHaveText('Logged in');
- })).toEqual(RoutePath.expired);
+ await expect(title).toHaveText('Account created');
+ await expect(subtitle).toHaveText('Logged in');
+ }),
+ ).toEqual(RoutePath.expired);
const outOfTimeTitle = page.getByTestId('title');
await expect(outOfTimeTitle).toHaveText('Congrats!');
@@ -65,15 +67,17 @@ test('App should create account', async () => {
});
test('App should become logged out', async () => {
- expect(await util.waitForNavigation(() => {
- exec('mullvad account logout');
- })).toEqual(RoutePath.login);
+ expect(
+ await util.waitForNavigation(() => {
+ exec('mullvad account logout');
+ }),
+ ).toEqual(RoutePath.login);
});
test('App should log in', async () => {
expect(await util.currentRoute()).toEqual(RoutePath.login);
- const title = page.locator('h1')
+ const title = page.locator('h1');
const subtitle = page.getByTestId('subtitle');
const loginInput = getInput(page);
@@ -82,25 +86,31 @@ test('App should log in', async () => {
await loginInput.fill(process.env.ACCOUNT_NUMBER!);
- expect(await util.waitForNavigation(async () => {
- await loginInput.press('Enter');
+ expect(
+ await util.waitForNavigation(async () => {
+ await loginInput.press('Enter');
- await expect(title).toHaveText('Logged in');
- await expect(subtitle).toHaveText('Valid account number');
- })).toEqual(RoutePath.main);
+ await expect(title).toHaveText('Logged in');
+ await expect(subtitle).toHaveText('Valid account number');
+ }),
+ ).toEqual(RoutePath.main);
await expectDisconnected(page);
});
test('App should log out', async () => {
- expect(await util.waitForNavigation(() => {
- void page.getByTestId('account-button').click();
- })).toEqual(RoutePath.account);
+ expect(
+ await util.waitForNavigation(() => {
+ void page.getByTestId('account-button').click();
+ }),
+ ).toEqual(RoutePath.account);
- expect(await util.waitForNavigation(() => {
- void page.getByText('Log out').click();
- })).toEqual(RoutePath.login);
+ expect(
+ await util.waitForNavigation(() => {
+ void page.getByText('Log out').click();
+ }),
+ ).toEqual(RoutePath.login);
- const title = page.locator('h1')
+ const title = page.locator('h1');
const subtitle = page.getByTestId('subtitle');
await expect(title).toHaveText('Login');
await expect(subtitle).toHaveText('Enter your account number');
@@ -109,7 +119,7 @@ test('App should log out', async () => {
test('App should log in to expired account', async () => {
expect(await util.currentRoute()).toEqual(RoutePath.login);
- const title = page.locator('h1')
+ const title = page.locator('h1');
const subtitle = page.getByTestId('subtitle');
const loginInput = getInput(page);
@@ -118,9 +128,11 @@ test('App should log in to expired account', async () => {
await loginInput.fill(accountNumber);
- expect(await util.waitForNavigation(async () => {
- await loginInput.press('Enter');
- })).toEqual(RoutePath.expired);
+ expect(
+ await util.waitForNavigation(async () => {
+ await loginInput.press('Enter');
+ }),
+ ).toEqual(RoutePath.expired);
const outOfTimeTitle = page.getByTestId('title');
await expect(outOfTimeTitle).toHaveText('Out of time');
diff --git a/gui/test/e2e/installed/state-dependent/macos-split-tunneling.spec.ts b/gui/test/e2e/installed/state-dependent/macos-split-tunneling.spec.ts
index 0f1680bf44..6d49173bcd 100644
--- a/gui/test/e2e/installed/state-dependent/macos-split-tunneling.spec.ts
+++ b/gui/test/e2e/installed/state-dependent/macos-split-tunneling.spec.ts
@@ -1,10 +1,10 @@
-import { Locator, expect, test } from '@playwright/test';
-import { Page } from 'playwright';
+import { expect, Locator, test } from '@playwright/test';
import { execSync } from 'child_process';
+import { Page } from 'playwright';
-import { startInstalledApp } from '../installed-utils';
-import { TestUtils } from '../../utils';
import { RoutePath } from '../../../../src/renderer/lib/routes';
+import { TestUtils } from '../../utils';
+import { startInstalledApp } from '../installed-utils';
// macOS only. This test expects the daemon to be logged in and for split tunneling to be off and
// have no split applications.
@@ -21,13 +21,13 @@ test.afterAll(async () => {
});
async function navigateToSplitTunneling() {
- await util.waitForNavigation(async () => await page.click('button[aria-label="Settings"]'));
+ await util.waitForNavigation(() => page.click('button[aria-label="Settings"]'));
- expect(
- await util.waitForNavigation(async () => await page.getByText('Split tunneling').click())
- ).toEqual(RoutePath.splitTunneling);
+ expect(await util.waitForNavigation(() => page.getByText('Split tunneling').click())).toEqual(
+ RoutePath.splitTunneling,
+ );
- const title = page.locator('h1')
+ const title = page.locator('h1');
await expect(title).toHaveText('Split tunneling');
}
@@ -46,7 +46,7 @@ test('App should enable split tunneling', async () => {
const launchPadApp = page.getByText('launchpad');
await expect(launchPadApp).not.toBeVisible();
- toggle.click();
+ await toggle.click();
await expect(toggle).toBeChecked();
await expect(splitList).not.toBeVisible();
await expect(nonSplitList).toBeVisible();
@@ -133,7 +133,7 @@ test('App should disable split tunneling', async () => {
const launchPadApp = page.getByText('launchpad');
await expect(launchPadApp).toBeVisible();
- toggle.click();
+ await toggle.click();
await expect(toggle).not.toBeChecked();
});
@@ -148,7 +148,7 @@ async function numberOfApplicationsInList(listTestid: string) {
return 0;
}
- return await list.locator('button').count();
+ return list.locator('button').count();
}
function getDaemonSplitTunnelingApplications() {
@@ -157,6 +157,7 @@ function getDaemonSplitTunnelingApplications() {
}
function isSplitInDaemon(app: string): boolean {
- return !!getDaemonSplitTunnelingApplications()
- .find((splitApp) => splitApp.toLowerCase().includes(app));
+ return !!getDaemonSplitTunnelingApplications().find((splitApp) =>
+ splitApp.toLowerCase().includes(app),
+ );
}
diff --git a/gui/test/e2e/installed/state-dependent/obfuscation.spec.ts b/gui/test/e2e/installed/state-dependent/obfuscation.spec.ts
index af72ded6d5..b9518f8717 100644
--- a/gui/test/e2e/installed/state-dependent/obfuscation.spec.ts
+++ b/gui/test/e2e/installed/state-dependent/obfuscation.spec.ts
@@ -2,10 +2,10 @@ import { expect, test } from '@playwright/test';
import { execSync } from 'child_process';
import { Page } from 'playwright';
-import { startInstalledApp } from '../installed-utils';
-import { TestUtils } from '../../utils';
import { colors } from '../../../../src/config.json';
import { RoutePath } from '../../../../src/renderer/lib/routes';
+import { TestUtils } from '../../utils';
+import { startInstalledApp } from '../installed-utils';
const SHADOWSOCKS_PORT = 65_000;
const UDPOVERTCP_PORT = '80';
@@ -25,14 +25,14 @@ test.afterAll(async () => {
});
test('App should have automatic obfuscation', async () => {
- await util.waitForNavigation(async () => await page.click('button[aria-label="Settings"]'));
- expect(
- await util.waitForNavigation(async () => await page.getByText('VPN settings').click()),
- ).toBe(RoutePath.vpnSettings);
+ await util.waitForNavigation(() => page.click('button[aria-label="Settings"]'));
+ expect(await util.waitForNavigation(() => page.getByText('VPN settings').click())).toBe(
+ RoutePath.vpnSettings,
+ );
- expect(
- await util.waitForNavigation(async () => await page.getByText('WireGuard settings').click()),
- ).toBe(RoutePath.wireguardSettings);
+ expect(await util.waitForNavigation(() => page.getByText('WireGuard settings').click())).toBe(
+ RoutePath.wireguardSettings,
+ );
const automatic = page.getByTestId('automatic-obfuscation');
await expect(automatic).toHaveCSS('background-color', colors.green);
@@ -45,9 +45,7 @@ test('App should have automatic obfuscation', async () => {
test('App should set obfuscation to shadowsocks with custom port', async () => {
expect(
- await util.waitForNavigation(
- async () => await page.click('button[aria-label="Shadowsocks settings"]'),
- ),
+ await util.waitForNavigation(() => page.click('button[aria-label="Shadowsocks settings"]')),
).toBe(RoutePath.shadowsocks);
const automatic = page.locator('button', { hasText: 'Automatic' });
@@ -61,7 +59,7 @@ test('App should set obfuscation to shadowsocks with custom port', async () => {
const customItem = page.locator('div[role="option"]', { hasText: 'Custom' });
await expect(customItem).toHaveCSS('background-color', colors.green);
- await util.waitForNavigation(async () => await page.click('button[aria-label="Back"]'));
+ await util.waitForNavigation(() => page.click('button[aria-label="Back"]'));
const shadowsocksItem = page.locator('button', { hasText: 'Shadowsocks' });
await shadowsocksItem.click();
@@ -74,22 +72,18 @@ test('App should set obfuscation to shadowsocks with custom port', async () => {
test('App should still have shadowsocks custom port', async () => {
expect(
- await util.waitForNavigation(
- async () => await page.click('button[aria-label="Shadowsocks settings"]'),
- ),
+ await util.waitForNavigation(() => page.click('button[aria-label="Shadowsocks settings"]')),
).toBe(RoutePath.shadowsocks);
const customItem = page.locator('div[role="option"]', { hasText: 'Custom' });
await expect(customItem).toHaveCSS('background-color', colors.green);
- await util.waitForNavigation(async () => await page.click('button[aria-label="Back"]'));
+ await util.waitForNavigation(() => page.click('button[aria-label="Back"]'));
});
test('App should set obfuscation to UDP-over-TCP with port', async () => {
expect(
- await util.waitForNavigation(
- async () => await page.click('button[aria-label="UDP-over-TCP settings"]'),
- ),
+ await util.waitForNavigation(() => page.click('button[aria-label="UDP-over-TCP settings"]')),
).toBe(RoutePath.udpOverTcp);
const automatic = page.locator('button', { hasText: 'Automatic' });
@@ -100,7 +94,7 @@ test('App should set obfuscation to UDP-over-TCP with port', async () => {
await expect(portButton).toHaveCSS('background-color', colors.green);
- await util.waitForNavigation(async () => await page.click('button[aria-label="Back"]'));
+ await util.waitForNavigation(() => page.click('button[aria-label="Back"]'));
const udpOverTcpItem = page.locator('button', { hasText: 'UDP-over-TCP' });
await udpOverTcpItem.click();
diff --git a/gui/test/e2e/installed/state-dependent/settings-import.spec.ts b/gui/test/e2e/installed/state-dependent/settings-import.spec.ts
index 6b37b36244..d9a8859f76 100644
--- a/gui/test/e2e/installed/state-dependent/settings-import.spec.ts
+++ b/gui/test/e2e/installed/state-dependent/settings-import.spec.ts
@@ -1,9 +1,9 @@
import { expect, test } from '@playwright/test';
import { Page } from 'playwright';
-import { startInstalledApp } from '../installed-utils';
-import { TestUtils } from '../../utils';
import { RoutePath } from '../../../../src/renderer/lib/routes';
+import { TestUtils } from '../../utils';
+import { startInstalledApp } from '../installed-utils';
const INVALID_JSON = 'invalid json';
const VALID_JSON = `
@@ -31,14 +31,14 @@ test.afterAll(async () => {
});
async function navigateToSettingsImport() {
- await util.waitForNavigation(async () => await page.click('button[aria-label="Settings"]'));
- await util.waitForNavigation(async () => await page.getByText('VPN settings').click());
+ await util.waitForNavigation(() => page.click('button[aria-label="Settings"]'));
+ await util.waitForNavigation(() => page.getByText('VPN settings').click());
- expect(
- await util.waitForNavigation(async () => await page.getByText('Server IP override').click())
- ).toEqual(RoutePath.settingsImport);
+ expect(await util.waitForNavigation(() => page.getByText('Server IP override').click())).toEqual(
+ RoutePath.settingsImport,
+ );
- const title = page.locator('h1')
+ const title = page.locator('h1');
await expect(title).toHaveText('Server IP override');
}
@@ -49,14 +49,14 @@ test('App should display no overrides', async () => {
});
test('App should fail to import text', async () => {
- expect(
- await util.waitForNavigation(async () => await page.getByText('Import via text').click())
- ).toEqual(RoutePath.settingsTextImport);
+ expect(await util.waitForNavigation(() => page.getByText('Import via text').click())).toEqual(
+ RoutePath.settingsTextImport,
+ );
await page.locator('textarea').fill(INVALID_JSON);
- expect(
- await util.waitForNavigation(async () => await page.click('button[aria-label="Save"]'))
- ).toEqual(RoutePath.settingsImport);
+ expect(await util.waitForNavigation(() => page.click('button[aria-label="Save"]'))).toEqual(
+ RoutePath.settingsImport,
+ );
await expect(page.getByTestId('status-title')).toHaveText('NO OVERRIDES IMPORTED');
await expect(page.getByTestId('status-subtitle')).toBeVisible();
@@ -65,16 +65,16 @@ test('App should fail to import text', async () => {
});
test('App should succeed to import text', async () => {
- expect(
- await util.waitForNavigation(async () => await page.getByText('Import via text').click())
- ).toEqual(RoutePath.settingsTextImport);
+ expect(await util.waitForNavigation(() => page.getByText('Import via text').click())).toEqual(
+ RoutePath.settingsTextImport,
+ );
const textarea = page.locator('textarea');
await expect(textarea).toHaveValue(INVALID_JSON);
await textarea.fill(VALID_JSON);
- expect(
- await util.waitForNavigation(async () => await page.click('button[aria-label="Save"]'))
- ).toEqual(RoutePath.settingsImport);
+ expect(await util.waitForNavigation(() => page.click('button[aria-label="Save"]'))).toEqual(
+ RoutePath.settingsImport,
+ );
await expect(page.getByTestId('status-title')).toHaveText('IMPORT SUCCESSFUL');
await expect(page.getByTestId('status-subtitle')).toBeVisible();
@@ -83,24 +83,24 @@ test('App should succeed to import text', async () => {
await expect(page.getByTestId('status-title')).toHaveText('OVERRIDES ACTIVE');
- expect(
- await util.waitForNavigation(async () => await page.getByText('Import via text').click())
- ).toEqual(RoutePath.settingsTextImport);
+ expect(await util.waitForNavigation(() => page.getByText('Import via text').click())).toEqual(
+ RoutePath.settingsTextImport,
+ );
await expect(textarea).toHaveValue('');
- expect(
- await util.waitForNavigation(async () => await page.click('button[aria-label="Close"]'))
- ).toEqual(RoutePath.settingsImport);
+ expect(await util.waitForNavigation(() => page.click('button[aria-label="Close"]'))).toEqual(
+ RoutePath.settingsImport,
+ );
});
test('App should show active overrides', async () => {
- expect(
- await util.waitForNavigation(async () => await page.click('button[aria-label="Back"]'))
- ).toEqual(RoutePath.vpnSettings);
- expect(
- await util.waitForNavigation(async () => await page.getByText('Server IP override').click())
- ).toEqual(RoutePath.settingsImport);
+ expect(await util.waitForNavigation(() => page.click('button[aria-label="Back"]'))).toEqual(
+ RoutePath.vpnSettings,
+ );
+ expect(await util.waitForNavigation(() => page.getByText('Server IP override').click())).toEqual(
+ RoutePath.settingsImport,
+ );
await expect(page.getByTestId('status-title')).toHaveText('OVERRIDES ACTIVE');
await expect(page.getByText('Clear all overrides')).toBeEnabled();
diff --git a/gui/test/e2e/installed/state-dependent/too-many-devices.spec.ts b/gui/test/e2e/installed/state-dependent/too-many-devices.spec.ts
index 9b6dbdbe3d..8ff8675b67 100644
--- a/gui/test/e2e/installed/state-dependent/too-many-devices.spec.ts
+++ b/gui/test/e2e/installed/state-dependent/too-many-devices.spec.ts
@@ -1,8 +1,8 @@
import { expect, test } from '@playwright/test';
import { Locator, Page } from 'playwright';
+
import { RoutePath } from '../../../../src/renderer/lib/routes';
import { TestUtils } from '../../utils';
-
import { startInstalledApp } from '../installed-utils';
// This test expects the daemon to be logged out and the provided account to have five registered
@@ -25,25 +25,26 @@ test('App should show too many devices', async () => {
expect(await util.currentRoute()).toEqual(RoutePath.login);
const loginInput = getInput(page);
- await loginInput.type(process.env.ACCOUNT_NUMBER!);
+ await loginInput.fill(process.env.ACCOUNT_NUMBER!);
- expect(await util.waitForNavigation(() => {
- loginInput.press('Enter');
- })).toEqual(RoutePath.tooManyDevices);
+ expect(await util.waitForNavigation(() => loginInput.press('Enter'))).toEqual(
+ RoutePath.tooManyDevices,
+ );
const loginButton = page.getByText('Continue with login');
await expect(page.getByTestId('title')).toHaveText('Too many devices');
await expect(loginButton).toBeDisabled();
- await page.getByLabel(/^Remove device named/).first().click();
+ await page
+ .getByLabel(/^Remove device named/)
+ .first()
+ .click();
await page.getByText('Yes, log out device').click();
await expect(loginButton).toBeEnabled();
// Trigger transition: too-many-devices -> login -> main
- expect(await util.waitForNavigation(() => {
- loginButton.click();
- })).toEqual(RoutePath.login);
+ expect(await util.waitForNavigation(() => loginButton.click())).toEqual(RoutePath.login);
// Note: `util.waitForNavigation` won't return the navigation event when
// transitioning from login -> main, so we need to observe the state of the
diff --git a/gui/test/e2e/installed/state-dependent/tunnel-state.spec.ts b/gui/test/e2e/installed/state-dependent/tunnel-state.spec.ts
index 53332ee6ab..15ce240e57 100644
--- a/gui/test/e2e/installed/state-dependent/tunnel-state.spec.ts
+++ b/gui/test/e2e/installed/state-dependent/tunnel-state.spec.ts
@@ -1,15 +1,11 @@
-import { exec as execAsync } from 'child_process';
-import { promisify } from 'util';
import { expect, test } from '@playwright/test';
+import { exec as execAsync } from 'child_process';
import { Page } from 'playwright';
-import {
- expectConnected,
- expectDisconnected,
- expectError,
-} from '../../shared/tunnel-state';
+import { promisify } from 'util';
-import { startInstalledApp } from '../installed-utils';
+import { expectConnected, expectDisconnected, expectError } from '../../shared/tunnel-state';
import { escapeRegExp } from '../../utils';
+import { startInstalledApp } from '../installed-utils';
const exec = promisify(execAsync);
@@ -164,7 +160,9 @@ test('App should show multihop', async () => {
await exec('mullvad relay set tunnel wireguard --use-multihop=on');
await expectConnected(page);
const relay = page.getByTestId('hostname-line');
- await expect(relay).toHaveText(new RegExp('^' + escapeRegExp(`${process.env.HOSTNAME} via`), 'i'));
+ await expect(relay).toHaveText(
+ new RegExp('^' + escapeRegExp(`${process.env.HOSTNAME} via`), 'i'),
+ );
await exec('mullvad relay set tunnel wireguard --use-multihop=off');
await page.getByText('Disconnect').click();
});
diff --git a/gui/test/e2e/mocked/expired-account-error-view.spec.ts b/gui/test/e2e/mocked/expired-account-error-view.spec.ts
index 5c906a134b..e63e62f51f 100644
--- a/gui/test/e2e/mocked/expired-account-error-view.spec.ts
+++ b/gui/test/e2e/mocked/expired-account-error-view.spec.ts
@@ -1,10 +1,11 @@
-import { Page } from 'playwright';
-import { MockedTestUtils, startMockedApp } from './mocked-utils';
import { expect, test } from '@playwright/test';
-import { IAccountData } from '../../../src/shared/daemon-rpc-types';
-import { getBackgroundColor } from '../utils';
+import { Page } from 'playwright';
+
import { colors } from '../../../src/config.json';
import { RoutePath } from '../../../src/renderer/lib/routes';
+import { IAccountData } from '../../../src/shared/daemon-rpc-types';
+import { getBackgroundColor } from '../utils';
+import { MockedTestUtils, startMockedApp } from './mocked-utils';
let page: Page;
let util: MockedTestUtils;
@@ -37,10 +38,12 @@ test('App should show out of time view after running out of time', async () => {
const expiryDate = new Date();
expiryDate.setSeconds(expiryDate.getSeconds() + 2);
- expect(await util.waitForNavigation(async () => {
- await util.sendMockIpcResponse<IAccountData>({
- channel: 'account-',
- response: { expiry: expiryDate.toISOString() },
- });
- })).toEqual(RoutePath.expired);
+ expect(
+ await util.waitForNavigation(async () => {
+ await util.sendMockIpcResponse<IAccountData>({
+ channel: 'account-',
+ response: { expiry: expiryDate.toISOString() },
+ });
+ }),
+ ).toEqual(RoutePath.expired);
});
diff --git a/gui/test/e2e/mocked/feature-indicators.spec.ts b/gui/test/e2e/mocked/feature-indicators.spec.ts
index 1ba216bd52..6e0e034c35 100644
--- a/gui/test/e2e/mocked/feature-indicators.spec.ts
+++ b/gui/test/e2e/mocked/feature-indicators.spec.ts
@@ -1,9 +1,14 @@
import { expect, test } from '@playwright/test';
import { Page } from 'playwright';
-import { MockedTestUtils, startMockedApp } from './mocked-utils';
-import { FeatureIndicator, ILocation, ITunnelEndpoint, TunnelState } from '../../../src/shared/daemon-rpc-types';
+import {
+ FeatureIndicator,
+ ILocation,
+ ITunnelEndpoint,
+ TunnelState,
+} from '../../../src/shared/daemon-rpc-types';
import { expectConnected } from '../shared/tunnel-state';
+import { MockedTestUtils, startMockedApp } from './mocked-utils';
const endpoint: ITunnelEndpoint = {
address: 'wg10:80',
@@ -91,23 +96,23 @@ test('App should show feature indicators', async () => {
await expect(ellipsis).toBeVisible();
await expectConnected(page);
- await expectFeatureIndicators(page, ["DAITA", "Quantum resistance"], false);
- await expectHiddenFeatureIndicator(page, "Mssfix");
+ await expectFeatureIndicators(page, ['DAITA', 'Quantum resistance'], false);
+ await expectHiddenFeatureIndicator(page, 'Mssfix');
await page.getByTestId('connection-panel-chevron').click();
await expect(ellipsis).not.toBeVisible();
await expectFeatureIndicators(page, [
- "DAITA",
- "Quantum resistance",
- "Mssfix",
- "MTU",
- "Obfuscation",
- "Local network sharing",
- "Lockdown mode",
- "Multihop",
- "Custom DNS",
- "Server IP override",
+ 'DAITA',
+ 'Quantum resistance',
+ 'Mssfix',
+ 'MTU',
+ 'Obfuscation',
+ 'Local network sharing',
+ 'Lockdown mode',
+ 'Multihop',
+ 'Custom DNS',
+ 'Server IP override',
]);
});
@@ -123,11 +128,7 @@ async function expectHiddenFeatureIndicator(page: Page, hiddenIndicator: string)
await expect(indicator).not.toBeVisible();
}
-async function expectFeatureIndicators(
- page: Page,
- expectedIndicators: Array<string>,
- only = true,
-) {
+async function expectFeatureIndicators(page: Page, expectedIndicators: Array<string>, only = true) {
const indicators = page.getByTestId('feature-indicator');
if (only) {
await expect(indicators).toHaveCount(expectedIndicators.length);
diff --git a/gui/test/e2e/mocked/mocked-utils.ts b/gui/test/e2e/mocked/mocked-utils.ts
index 1840ebbbb0..57998fae68 100644
--- a/gui/test/e2e/mocked/mocked-utils.ts
+++ b/gui/test/e2e/mocked/mocked-utils.ts
@@ -3,7 +3,7 @@ import { ElectronApplication } from 'playwright';
import { startApp, TestUtils } from '../utils';
interface StartMockedAppResponse extends Awaited<ReturnType<typeof startApp>> {
- util: MockedTestUtils,
+ util: MockedTestUtils;
}
export interface MockedTestUtils extends TestUtils {
@@ -22,7 +22,7 @@ export const startMockedApp = async (): Promise<StartMockedAppResponse> => {
...startAppResult.util,
mockIpcHandle,
sendMockIpcResponse,
- }
+ },
};
};
diff --git a/gui/test/e2e/mocked/settings.spec.ts b/gui/test/e2e/mocked/settings.spec.ts
index c6022678f5..52dbc72402 100644
--- a/gui/test/e2e/mocked/settings.spec.ts
+++ b/gui/test/e2e/mocked/settings.spec.ts
@@ -1,8 +1,8 @@
import { expect, test } from '@playwright/test';
import { Page } from 'playwright';
-import { MockedTestUtils, startMockedApp } from './mocked-utils';
import { IAccountData } from '../../../src/shared/daemon-rpc-types';
+import { MockedTestUtils, startMockedApp } from './mocked-utils';
let page: Page;
let util: MockedTestUtils;
@@ -21,7 +21,7 @@ test('Account button should be displayed correctly', async () => {
});
test('Headerbar account info should be displayed correctly', async () => {
- let expiryText = page.getByText(/^Time left:/);
+ const expiryText = page.getByText(/^Time left:/);
await expect(expiryText).toContainText(/Time left: 29 days/i);
/**
diff --git a/gui/test/e2e/mocked/tunnel-state.spec.ts b/gui/test/e2e/mocked/tunnel-state.spec.ts
index 3e20dab6ec..6ecf707ba6 100644
--- a/gui/test/e2e/mocked/tunnel-state.spec.ts
+++ b/gui/test/e2e/mocked/tunnel-state.spec.ts
@@ -1,9 +1,20 @@
import { test } from '@playwright/test';
import { Page } from 'playwright';
+import {
+ ErrorStateCause,
+ ILocation,
+ ITunnelEndpoint,
+ TunnelState,
+} from '../../../src/shared/daemon-rpc-types';
+import {
+ expectConnected,
+ expectConnecting,
+ expectDisconnected,
+ expectDisconnecting,
+ expectError,
+} from '../shared/tunnel-state';
import { MockedTestUtils, startMockedApp } from './mocked-utils';
-import { ErrorStateCause, ILocation, ITunnelEndpoint, TunnelState } from '../../../src/shared/daemon-rpc-types';
-import { expectConnected, expectConnecting, expectDisconnected, expectDisconnecting, expectError } from '../shared/tunnel-state';
const mockLocation: ILocation = {
country: 'Sweden',
diff --git a/gui/test/e2e/shared/tunnel-state.ts b/gui/test/e2e/shared/tunnel-state.ts
index 4d75f79d01..6a5fbfaf09 100644
--- a/gui/test/e2e/shared/tunnel-state.ts
+++ b/gui/test/e2e/shared/tunnel-state.ts
@@ -1,5 +1,6 @@
import { expect } from '@playwright/test';
import { Page } from 'playwright';
+
import { colors } from '../../../src/config.json';
import { anyOf } from '../utils';
diff --git a/gui/test/e2e/utils.ts b/gui/test/e2e/utils.ts
index 082ccfcf3f..2fb33319f2 100644
--- a/gui/test/e2e/utils.ts
+++ b/gui/test/e2e/utils.ts
@@ -1,4 +1,4 @@
-import { Locator, Page, _electron as electron, ElectronApplication } from 'playwright';
+import { _electron as electron, ElectronApplication, Locator, Page } from 'playwright';
export interface StartAppResponse {
app: ElectronApplication;
@@ -8,7 +8,7 @@ export interface StartAppResponse {
export interface TestUtils {
currentRoute: () => Promise<string>;
- waitForNavigation: (initiateNavigation?: () => Promise<void> | void) => Promise<string>;
+ waitForNavigation: (initiateNavigation?: () => Promise<void> | void) => Promise<string>;
waitForNoTransition: () => Promise<void>;
}
@@ -38,34 +38,28 @@ export const startApp = async (options: LaunchOptions): Promise<StartAppResponse
return { app, page, util };
};
-export const launch = async (options: LaunchOptions): Promise<ElectronApplication> => {
+export const launch = (options: LaunchOptions): Promise<ElectronApplication> => {
process.env.CI = 'e2e';
- return await electron.launch(options);
-}
+ return electron.launch(options);
+};
const currentRouteFactory = (app: ElectronApplication) => {
- return async () => {
- return await app.evaluate<string>(({ webContents }) => {
- return webContents.getAllWebContents()
- // Select window that isn't devtools
- .find((webContents) => webContents.getURL().startsWith('file://'))!
- .executeJavaScript('window.e2e.location');
- });
- };
-}
+ return () =>
+ app.evaluate<string>(({ webContents }) =>
+ webContents
+ .getAllWebContents()
+ // Select window that isn't devtools
+ .find((webContents) => webContents.getURL().startsWith('file://'))!
+ .executeJavaScript('window.e2e.location'),
+ );
+};
-const waitForNavigationFactory = (
- app: ElectronApplication,
- page: Page,
-) => {
+const waitForNavigationFactory = (app: ElectronApplication, page: Page) => {
// Wait for navigation animation to finish. A function can be provided that initiates the
// navigation, e.g. clicks a button.
return async (initiateNavigation?: () => Promise<void> | void) => {
// Wait for route to change after optionally initiating the navigation.
- const [route] = await Promise.all([
- waitForNextRoute(app),
- initiateNavigation?.(),
- ]);
+ const [route] = await Promise.all([waitForNextRoute(app), initiateNavigation?.()]);
// Wait for view corresponding to new route to appear
await page.getByTestId(route).isVisible();
@@ -77,7 +71,7 @@ const waitForNavigationFactory = (
const waitForNoTransition = async (page: Page) => {
// Wait until there's only one transitionContents
- let transitionContentsCount;
+ let transitionContentsCount;
do {
if (transitionContentsCount !== undefined) {
await new Promise((resolve) => setTimeout(resolve, 5));
@@ -93,14 +87,15 @@ const waitForNoTransition = async (page: Page) => {
};
// Returns the route when it changes
-const waitForNextRoute = async (app: ElectronApplication): Promise<string> => {
- return await app.evaluate(({ ipcMain }) => {
- return new Promise((resolve) => {
- ipcMain.once('navigation-setHistory', (_event, history: History) => {
+const waitForNextRoute = (app: ElectronApplication): Promise<string> => {
+ return app.evaluate(
+ ({ ipcMain }) =>
+ new Promise((resolve) => {
+ ipcMain.once('navigation-setHistory', (_event, history: History) => {
resolve(history.entries[history.index].pathname);
- });
- });
- });
+ });
+ }),
+ );
};
const getStyleProperty = (locator: Locator, property: string) => {
@@ -125,5 +120,5 @@ export function anyOf(...values: string[]): RegExp {
}
export function escapeRegExp(regexp: string): string {
- return regexp.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
+ return regexp.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
diff --git a/gui/test/unit/account-data-cache.spec.ts b/gui/test/unit/account-data-cache.spec.ts
index f3d6df3142..cf1c4299d8 100644
--- a/gui/test/unit/account-data-cache.spec.ts
+++ b/gui/test/unit/account-data-cache.spec.ts
@@ -1,7 +1,8 @@
+import { expect, spy } from 'chai';
+import sinon from 'sinon';
+
import AccountDataCache, { AccountFetchError } from '../../src/main/account-data-cache';
import { AccountDataResponse, IAccountData } from '../../src/shared/daemon-rpc-types';
-import sinon from 'sinon';
-import { expect, spy } from 'chai';
describe('IAccountData cache', () => {
const dummyAccountToken = '9876543210';
@@ -44,7 +45,7 @@ describe('IAccountData cache', () => {
const watcher = new Promise<void>((resolve, reject) => {
cache.fetch(dummyAccountToken, {
- onFinish: (_reason?: any) => resolve(),
+ onFinish: () => resolve(),
onError: (_error: AccountFetchError) => reject(),
});
});
@@ -254,9 +255,7 @@ describe('IAccountData cache', () => {
await new Promise((resolve) => setTimeout(resolve));
cache.fetch(dummyAccountToken, {
- onFinish: async () => {
- resolve();
- },
+ onFinish: () => resolve(),
onError: (_error: AccountFetchError) => reject(),
});
},
@@ -298,9 +297,7 @@ describe('IAccountData cache', () => {
await new Promise((resolve) => setTimeout(resolve));
cache.fetch(dummyAccountToken, {
- onFinish: async () => {
- resolve();
- },
+ onFinish: () => resolve(),
onError: (_error: AccountFetchError) => reject(),
});
},
diff --git a/gui/test/unit/changelog.spec.ts b/gui/test/unit/changelog.spec.ts
index 249c26e1db..774dca956b 100644
--- a/gui/test/unit/changelog.spec.ts
+++ b/gui/test/unit/changelog.spec.ts
@@ -1,5 +1,6 @@
import { expect } from 'chai';
-import { after, it, describe } from 'mocha';
+import { after, describe, it } from 'mocha';
+
import { parseChangelog } from '../../src/main/changelog';
// It should be handled the same no matter if the platforms are split with a space or not.
diff --git a/gui/test/unit/date-helper.spec.ts b/gui/test/unit/date-helper.spec.ts
index 74500ff960..82c4faeac7 100644
--- a/gui/test/unit/date-helper.spec.ts
+++ b/gui/test/unit/date-helper.spec.ts
@@ -1,5 +1,6 @@
import { expect } from 'chai';
-import { it, describe } from 'mocha';
+import { describe, it } from 'mocha';
+
import * as date from '../../src/shared/date-helper';
describe('Date helper', () => {
@@ -100,76 +101,61 @@ describe('Date helper', () => {
});
it('should format positive difference as string', () => {
- const diff1 = date.formatRelativeDate(
- '2021-01-01 13:37:10',
- '2021-01-01 13:37:20',
- { displayMonths: true },
- );
+ const diff1 = date.formatRelativeDate('2021-01-01 13:37:10', '2021-01-01 13:37:20', {
+ displayMonths: true,
+ });
expect(diff1).to.equal('less than a day');
- const diff2 = date.formatRelativeDate(
- '2021-01-01 13:37:10',
- '2021-01-02 13:37:20',
- { displayMonths: true },
- );
+ const diff2 = date.formatRelativeDate('2021-01-01 13:37:10', '2021-01-02 13:37:20', {
+ displayMonths: true,
+ });
expect(diff2).to.equal('1 day');
- const diff3 = date.formatRelativeDate(
- '2021-01-01 13:37:10',
- '2021-02-25 13:37:20',
- { displayMonths: true },
- );
+ const diff3 = date.formatRelativeDate('2021-01-01 13:37:10', '2021-02-25 13:37:20', {
+ displayMonths: true,
+ });
expect(diff3).to.equal('55 days');
- const diff4 = date.formatRelativeDate(
- '2021-01-01 13:37:10',
- '2021-04-25 13:37:20',
- { displayMonths: true },
- );
+ const diff4 = date.formatRelativeDate('2021-01-01 13:37:10', '2021-04-25 13:37:20', {
+ displayMonths: true,
+ });
expect(diff4).to.equal('3 months');
- const diff5 = date.formatRelativeDate(
- '2021-01-01 13:37:10',
- '2031-04-25 13:37:20',
- { displayMonths: true },
- );
+ const diff5 = date.formatRelativeDate('2021-01-01 13:37:10', '2031-04-25 13:37:20', {
+ displayMonths: true,
+ });
expect(diff5).to.equal('10 years');
});
it('should format positive difference as string suffixed with "left"', () => {
- const diff1 = date.formatRelativeDate(
- '2021-01-01 13:37:10',
- '2021-01-01 13:37:20',
- { suffix: true, displayMonths: true },
- );
+ const diff1 = date.formatRelativeDate('2021-01-01 13:37:10', '2021-01-01 13:37:20', {
+ suffix: true,
+ displayMonths: true,
+ });
expect(diff1).to.equal('less than a day left');
- const diff2 = date.formatRelativeDate(
- '2021-01-01 13:37:10',
- '2021-01-02 13:37:20',
- { suffix: true, displayMonths: true },
- );
+ const diff2 = date.formatRelativeDate('2021-01-01 13:37:10', '2021-01-02 13:37:20', {
+ suffix: true,
+ displayMonths: true,
+ });
expect(diff2).to.equal('1 day left');
- const diff3 = date.formatRelativeDate(
- '2021-01-01 13:37:10',
- '2021-02-25 13:37:20',
- { suffix: true, displayMonths: true },
- );
+ const diff3 = date.formatRelativeDate('2021-01-01 13:37:10', '2021-02-25 13:37:20', {
+ suffix: true,
+ displayMonths: true,
+ });
expect(diff3).to.equal('55 days left');
- const diff4 = date.formatRelativeDate(
- '2021-01-01 13:37:10',
- '2021-04-25 13:37:20',
- { suffix: true, displayMonths: true },
- );
+ const diff4 = date.formatRelativeDate('2021-01-01 13:37:10', '2021-04-25 13:37:20', {
+ suffix: true,
+ displayMonths: true,
+ });
expect(diff4).to.equal('3 months left');
- const diff5 = date.formatRelativeDate(
- '2021-01-01 13:37:10',
- '2031-04-25 13:37:20',
- { suffix: true, displayMonths: true },
- );
+ const diff5 = date.formatRelativeDate('2021-01-01 13:37:10', '2031-04-25 13:37:20', {
+ suffix: true,
+ displayMonths: true,
+ });
expect(diff5).to.equal('10 years left');
});
diff --git a/gui/test/unit/history.spec.ts b/gui/test/unit/history.spec.ts
index 03eabd80cc..739c65c5ca 100644
--- a/gui/test/unit/history.spec.ts
+++ b/gui/test/unit/history.spec.ts
@@ -1,5 +1,6 @@
import { expect, spy } from 'chai';
-import { it, describe, beforeEach } from 'mocha';
+import { beforeEach, describe, it } from 'mocha';
+
import History from '../../src/renderer/lib/history';
import { RoutePath } from '../../src/renderer/lib/routes';
diff --git a/gui/test/unit/ip.spec.ts b/gui/test/unit/ip.spec.ts
index 10b93bc890..5f6a265d25 100644
--- a/gui/test/unit/ip.spec.ts
+++ b/gui/test/unit/ip.spec.ts
@@ -1,5 +1,6 @@
import { expect } from 'chai';
-import { it, describe } from 'mocha';
+import { describe, it } from 'mocha';
+
import * as ip from '../../src/renderer/lib/ip';
const validIpv4Addresses = [
diff --git a/gui/test/unit/keyframe-animation.spec.ts b/gui/test/unit/keyframe-animation.spec.ts
index 59b5c2d6f7..0ba302e65c 100644
--- a/gui/test/unit/keyframe-animation.spec.ts
+++ b/gui/test/unit/keyframe-animation.spec.ts
@@ -1,5 +1,6 @@
import { expect } from 'chai';
-import { it, describe } from 'mocha';
+import { describe, it } from 'mocha';
+
import KeyframeAnimation from '../../src/main/keyframe-animation';
describe('lib/keyframe-animation', function () {
diff --git a/gui/test/unit/list-diff.spec.ts b/gui/test/unit/list-diff.spec.ts
index 9357579072..e64d79b193 100644
--- a/gui/test/unit/list-diff.spec.ts
+++ b/gui/test/unit/list-diff.spec.ts
@@ -1,5 +1,6 @@
import { expect } from 'chai';
-import { it, describe } from 'mocha';
+import { describe, it } from 'mocha';
+
import { calculateItemList, RowDisplayData } from '../../src/renderer/components/List';
const prevItems: Array<RowDisplayData<undefined>> = [
diff --git a/gui/test/unit/logging.spec.ts b/gui/test/unit/logging.spec.ts
index d107a23d3b..393b631ba5 100644
--- a/gui/test/unit/logging.spec.ts
+++ b/gui/test/unit/logging.spec.ts
@@ -1,10 +1,11 @@
import { expect, spy } from 'chai';
import fs from 'fs';
-import sinon from 'sinon';
-import { it, describe, before, beforeEach, after } from 'mocha';
+import { after, before, beforeEach, describe, it } from 'mocha';
import path from 'path';
-import { Logger } from '../../src/shared/logging';
+import sinon from 'sinon';
+
import { backupLogFile, rotateOrDeleteFile } from '../../src/main/logging';
+import { Logger } from '../../src/shared/logging';
import { LogLevel } from '../../src/shared/logging-types';
const aPath = path.normalize('log-directory/a.log');
diff --git a/gui/test/unit/notification-evaluation.spec.ts b/gui/test/unit/notification-evaluation.spec.ts
index 27de83cf29..723307b3d7 100644
--- a/gui/test/unit/notification-evaluation.spec.ts
+++ b/gui/test/unit/notification-evaluation.spec.ts
@@ -1,21 +1,25 @@
import { expect } from 'chai';
-import { it, describe } from 'mocha';
+import { describe, it } from 'mocha';
import sinon from 'sinon';
-import {
- UnsupportedVersionNotificationProvider,
- UpdateAvailableNotificationProvider,
-} from '../../src/shared/notifications/notification';
import NotificationController from '../../src/main/notification-controller';
import { TunnelState } from '../../src/shared/daemon-rpc-types';
import { ErrorStateCause } from '../../src/shared/daemon-rpc-types';
import { FirewallPolicyErrorType } from '../../src/shared/daemon-rpc-types';
+import {
+ UnsupportedVersionNotificationProvider,
+ UpdateAvailableNotificationProvider,
+} from '../../src/shared/notifications/notification';
function createController() {
return new NotificationController({
- openApp: () => { /* no-op */ },
+ openApp: () => {
+ /* no-op */
+ },
openLink: (_url: string, _withAuth?: boolean) => Promise.resolve(),
- showNotificationIcon: (_value: boolean) => { /* no-op */ },
+ showNotificationIcon: (_value: boolean) => {
+ /* no-op */
+ },
});
}
@@ -26,10 +30,18 @@ describe('System notifications', () => {
sandbox = sinon.createSandbox();
// @ts-ignore
sandbox.stub(NotificationController.prototype, 'createElectronNotification').returns({
- show: () => { /* no-op */ },
- close: () => { /* no-op */ },
- on: () => { /* no-op */ },
- removeAllListeners: () => { /* no-op */ },
+ show: () => {
+ /* no-op */
+ },
+ close: () => {
+ /* no-op */
+ },
+ on: () => {
+ /* no-op */
+ },
+ removeAllListeners: () => {
+ /* no-op */
+ },
});
});
@@ -133,7 +145,7 @@ describe('System notifications', () => {
cause: ErrorStateCause.isOffline,
blockingError: {
type: FirewallPolicyErrorType.generic,
- }
+ },
},
};
const result6 = controller.notifyTunnelState(nonBlockingErrorState, false, false, false, false);
diff --git a/gui/test/unit/setup.ts b/gui/test/unit/setup.ts
index 65644e28d9..a565ec50ca 100644
--- a/gui/test/unit/setup.ts
+++ b/gui/test/unit/setup.ts
@@ -1,6 +1,6 @@
import chai from 'chai';
-import spies from 'chai-spies';
import chaiAsPromised from 'chai-as-promised';
+import spies from 'chai-spies';
chai.use(spies);
chai.use(chaiAsPromised);
diff --git a/gui/test/unit/tunnel-state.spec.ts b/gui/test/unit/tunnel-state.spec.ts
index d4629ebc64..a6013523b8 100644
--- a/gui/test/unit/tunnel-state.spec.ts
+++ b/gui/test/unit/tunnel-state.spec.ts
@@ -1,6 +1,7 @@
import { expect, spy } from 'chai';
-import { it, describe } from 'mocha';
+import { describe, it } from 'mocha';
import sinon from 'sinon';
+
import TunnelStateHandler from '../../src/main/tunnel-state';
import { TunnelState } from '../../src/shared/daemon-rpc-types';
@@ -106,4 +107,3 @@ describe('Tunnel state', () => {
clock.restore();
});
});
-