Upgrade eslint to latest (#2763)

Update ESLint to the latest version, and migrate to new configuration file
This commit is contained in:
Sami Vänttinen 2025-11-17 11:34:52 +02:00 committed by GitHub
parent 9591aa27ef
commit b1b6581d50
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 718 additions and 873 deletions

202
.eslintrc
View file

@ -1,202 +0,0 @@
{
"extends": "eslint:recommended",
"ignorePatterns": ["**/*.min.js"],
"env": {
"browser": true,
"es2022": true,
"jquery": true,
"webextensions": true
},
"parserOptions": {
"ecmaVersion": 13
},
"rules": {
"array-bracket-spacing": ["error", "always"],
"arrow-body-style": "warn",
"arrow-parens": "off",
"arrow-spacing": "warn",
"block-scoped-var": "off",
"brace-style": ["warn", "1tbs"],
"camelcase": "warn",
"class-methods-use-this": "off",
"comma-dangle": "off",
"computed-property-spacing": ["error", "never"],
"consistent-return": "off",
"dot-notation": "off",
"eqeqeq": "error",
"func-names": "off",
"function-paren-newline": "off",
"guard-for-in": "off",
"implicit-arrow-linebreak": "off",
"indent": ["error", 4],
"linebreak-style": ["error", "unix"],
"lines-around-comment": "off",
"max-len": "off",
"no-alert": "error",
"no-await-in-loop": "off",
"no-bitwise": "off",
"no-console": "off",
"no-continue": "off",
"no-control-regex": "off",
"no-else-return": "off",
"no-empty-function": ["error", { "allow": ["arrowFunctions", "methods", "asyncMethods"] }],
"no-extend-native": "off",
"no-global-assign": "off",
"no-lonely-if": "off",
"no-loop-func": "off",
"no-mixed-operators": "off",
"no-mixed-spaces-and-tabs": ["error", "smart-tabs"],
"no-multi-spaces": "warn",
"no-param-reassign": "off",
"no-plusplus": "off",
"no-prototype-builtins": "off",
"no-redeclare": "off",
"no-restricted-globals": "off",
"no-restricted-syntax": "off",
"no-return-await": "off",
"no-tabs": "warn",
"no-underscore-dangle": "off",
"no-unused-vars": ["warn", { "args": "none", "varsIgnorePattern": "[A-Z_]+|tr|[$]" }],
"no-use-before-define": "off",
"no-useless-escape": "off",
"no-useless-return": "off",
"no-var": "error",
"object-curly-spacing": ["warn", "always"],
"object-shorthand": "off",
"operator-linebreak": "off",
"prefer-arrow-callback": "off",
"prefer-const": "warn",
"prefer-destructuring": "off",
"prefer-template": "off",
"quote-props": "off",
"quotes": ["error", "single", { "avoidEscape": true }],
"semi": ["error", "always"],
"space-before-blocks": "warn",
"space-before-function-paren": "off",
"space-in-parens": ["error", "never"],
"space-unary-ops": "off",
"spaced-comment": "off",
"strict": "off",
"vars-on-top": "off"
},
"globals": {
"_called": "readonly",
"acceptedOTPFields": "readonly",
"assertInputFields": "readonly",
"assertPasswordChangeFields": "readonly",
"assertRegex": "readonly",
"assertSearchField": "readonly",
"assertSearchForm": "readonly",
"assertTOTPField": "readonly",
"AssociatedAction": "readonly",
"AuthenticatorAssertionResponse": "readonly",
"AuthenticatorAttestationResponse": "readonly",
"Autocomplete": "readonly",
"BannerPosition": "readonly",
"BLUE_BUTTON": "readonly",
"bootstrap": "readonly",
"browser": "readonly",
"browserAction": "readonly",
"CHECK_UPDATE_NEVER": "readonly",
"CHECK_UPDATE_ONE_MONTH": "readonly",
"CHECK_UPDATE_ONE_WEEK": "readonly",
"CHECK_UPDATE_THREE_DAYS": "readonly",
"cloneInto": "readonly",
"compareVersion": "readonly",
"createResult": "readonly",
"createStylesheet": "readonly",
"DatabaseState": "readonly",
"debugLogMessage": "readonly",
"DEFINED_CUSTOM_FIELDS": "readonly",
"elementsOverlap": "readonly",
"EXTENSION_NAME": "readonly",
"getCurrentTab": "readonly",
"getLoginData": "readonly",
"getTopLevelDomainFromUrl": "readonly",
"GRAY_BUTTON_CLASS": "readonly",
"GREEN_BUTTON": "readonly",
"httpAuth": "readonly",
"Icon": "readonly",
"IGNORE_AUTOSUBMIT": "readonly",
"IGNORE_FULL": "readonly",
"IGNORE_NORMAL": "readonly",
"IGNORE_NOTHING": "readonly",
"IGNORE_PASSKEYS": "readonly",
"importScripts": "readonly",
"IMPROVED_DETECTION_PREDEFINED_SITELIST": "readonly",
"initColorTheme": "readonly",
"isEdge": "readonly",
"isElementInside": "readonly",
"isFirefox": "readonly",
"isIframeAllowed": "readonly",
"keepass": "readonly",
"keepassClient": "readonly",
"kpActions": "readonly",
"kpErrors": "readonly",
"kpxc": "readonly",
"kpxcAssert": "readonly",
"kpxcBanner": "readonly",
"kpxcCustomLoginFieldsBanner": "readonly",
"kpxcEvent": "readonly",
"kpxcFields": "readonly",
"kpxcFill": "readonly",
"kpxcForm": "readonly",
"kpxcIcons": "readonly",
"kpxcObserverHelper": "readonly",
"kpxcPasswordGenerator": "readonly",
"kpxcPasswordIcons": "readonly",
"kpxcSites": "readonly",
"kpxcTOTPAutocomplete": "readonly",
"kpxcTOTPIcons": "readonly",
"kpxcUI": "readonly",
"kpxcUserAutocomplete": "readonly",
"kpxcUsernameIcons": "readonly",
"logDebug": "readonly",
"logError": "readonly",
"kpxcPasskeysUtils": "readonly",
"ManualFill": "readonly",
"matchesWithNodeName": "readonly",
"MAX_AUTOCOMPLETE_NAME_LEN": "readonly",
"MAX_OPACITY": "readonly",
"MAX_TOTP_INPUT_LENGTH": "readonly",
"menuContexts": "readonly",
"MIN_INPUT_FIELD_OFFSET_WIDTH": "readonly",
"MIN_INPUT_FIELD_WIDTH_PX": "readonly",
"MIN_OPACITY": "readonly",
"MIN_TOTP_INPUT_LENGTH": "readonly",
"module": "readonly",
"nacl": "readonly",
"OBSERVER_OPTIONS": "readonly",
"ORANGE_BUTTON": "readonly",
"page": "readonly",
"Pixels": "readonly",
"PublicKeyCredential": "readonly",
"PREDEFINED_SITELIST": "readonly",
"RED_BUTTON": "readonly",
"retrieveColorScheme": "readonly",
"sendMessage": "readonly",
"showNotification": "readonly",
"siteMatch": "readonly",
"SitePreferences": "readonly",
"slashNeededForUrl": "readonly",
"SORT_BY_GROUP_AND_TITLE": "readonly",
"SORT_BY_GROUP_AND_USERNAME": "readonly",
"SORT_BY_MATCHING_CREDENTIALS_SETTING": "readonly",
"SORT_BY_RELEVANT_ENTRY": "readonly",
"SORT_BY_TITLE": "readonly",
"SORT_BY_USERNAME": "readonly",
"statusResponse": "readonly",
"Tests": "readonly",
"tr": "readonly",
"trimURL": "readonly",
"updateDefaultPasswordManager": "readonly"
},
"overrides": [
{
"files": ["./*.js"],
"env": {
"node": true
}
}
]
}

214
eslint.config.mjs Normal file
View file

@ -0,0 +1,214 @@
import { defineConfig, globalIgnores } from "eslint/config";
import globals from "globals";
import path from "node:path";
import { fileURLToPath } from "node:url";
import js from "@eslint/js";
import { FlatCompat } from "@eslint/eslintrc";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all
});
export default defineConfig([globalIgnores(["**/*.min.js"]), {
extends: compat.extends("eslint:recommended"),
languageOptions: {
globals: {
...globals.browser,
...globals.jquery,
...globals.webextensions,
_called: "readonly",
acceptedOTPFields: "readonly",
assertInputFields: "readonly",
assertPasswordChangeFields: "readonly",
assertRegex: "readonly",
assertSearchField: "readonly",
assertSearchForm: "readonly",
assertTOTPField: "readonly",
AssociatedAction: "readonly",
AuthenticatorAssertionResponse: "readonly",
AuthenticatorAttestationResponse: "readonly",
Autocomplete: "readonly",
BannerPosition: "readonly",
BLUE_BUTTON: "readonly",
bootstrap: "readonly",
browser: "readonly",
browserAction: "readonly",
CHECK_UPDATE_NEVER: "readonly",
CHECK_UPDATE_ONE_MONTH: "readonly",
CHECK_UPDATE_ONE_WEEK: "readonly",
CHECK_UPDATE_THREE_DAYS: "readonly",
cloneInto: "readonly",
compareVersion: "readonly",
createResult: "readonly",
createStylesheet: "readonly",
DatabaseState: "readonly",
debugLogMessage: "readonly",
DEFINED_CUSTOM_FIELDS: "readonly",
elementsOverlap: "readonly",
EXTENSION_NAME: "readonly",
getCurrentTab: "readonly",
getLoginData: "readonly",
getTopLevelDomainFromUrl: "readonly",
GRAY_BUTTON_CLASS: "readonly",
GREEN_BUTTON: "readonly",
httpAuth: "readonly",
Icon: "readonly",
IGNORE_AUTOSUBMIT: "readonly",
IGNORE_FULL: "readonly",
IGNORE_NORMAL: "readonly",
IGNORE_NOTHING: "readonly",
IGNORE_PASSKEYS: "readonly",
importScripts: "readonly",
IMPROVED_DETECTION_PREDEFINED_SITELIST: "readonly",
initColorTheme: "readonly",
isEdge: "readonly",
isElementInside: "readonly",
isFirefox: "readonly",
isIframeAllowed: "readonly",
keepass: "readonly",
keepassClient: "readonly",
kpActions: "readonly",
kpErrors: "readonly",
kpxc: "readonly",
kpxcAssert: "readonly",
kpxcBanner: "readonly",
kpxcCustomLoginFieldsBanner: "readonly",
kpxcEvent: "readonly",
kpxcFields: "readonly",
kpxcFill: "readonly",
kpxcForm: "readonly",
kpxcIcons: "readonly",
kpxcObserverHelper: "readonly",
kpxcPasswordGenerator: "readonly",
kpxcPasswordIcons: "readonly",
kpxcSites: "readonly",
kpxcTOTPAutocomplete: "readonly",
kpxcTOTPIcons: "readonly",
kpxcUI: "readonly",
kpxcUserAutocomplete: "readonly",
kpxcUsernameIcons: "readonly",
logDebug: "readonly",
logError: "readonly",
kpxcPasskeysUtils: "readonly",
ManualFill: "readonly",
matchesWithNodeName: "readonly",
MAX_AUTOCOMPLETE_NAME_LEN: "readonly",
MAX_OPACITY: "readonly",
MAX_TOTP_INPUT_LENGTH: "readonly",
menuContexts: "readonly",
MIN_INPUT_FIELD_OFFSET_WIDTH: "readonly",
MIN_INPUT_FIELD_WIDTH_PX: "readonly",
MIN_OPACITY: "readonly",
MIN_TOTP_INPUT_LENGTH: "readonly",
module: "readonly",
nacl: "readonly",
OBSERVER_OPTIONS: "readonly",
ORANGE_BUTTON: "readonly",
page: "readonly",
Pixels: "readonly",
PublicKeyCredential: "readonly",
PREDEFINED_SITELIST: "readonly",
RED_BUTTON: "readonly",
retrieveColorScheme: "readonly",
sendMessage: "readonly",
showNotification: "readonly",
siteMatch: "readonly",
SitePreferences: "readonly",
slashNeededForUrl: "readonly",
SORT_BY_GROUP_AND_TITLE: "readonly",
SORT_BY_GROUP_AND_USERNAME: "readonly",
SORT_BY_MATCHING_CREDENTIALS_SETTING: "readonly",
SORT_BY_RELEVANT_ENTRY: "readonly",
SORT_BY_TITLE: "readonly",
SORT_BY_USERNAME: "readonly",
statusResponse: "readonly",
Tests: "readonly",
tr: "readonly",
trimURL: "readonly",
updateDefaultPasswordManager: "readonly",
},
ecmaVersion: 13,
sourceType: "script",
},
rules: {
"array-bracket-spacing": ["error", "always"],
"arrow-body-style": "warn",
"arrow-parens": "off",
"arrow-spacing": "warn",
"block-scoped-var": "off",
"brace-style": ["warn", "1tbs"],
"camelcase": "warn",
"class-methods-use-this": "off",
"comma-dangle": "off",
"computed-property-spacing": ["error", "never"],
"consistent-return": "off",
"dot-notation": "off",
"eqeqeq": "error",
"func-names": "off",
"function-paren-newline": "off",
"guard-for-in": "off",
"implicit-arrow-linebreak": "off",
"indent": ["error", 4],
"linebreak-style": ["error", "unix"],
"lines-around-comment": "off",
"max-len": "off",
"no-alert": "error",
"no-await-in-loop": "off",
"no-bitwise": "off",
"no-console": "off",
"no-continue": "off",
"no-control-regex": "off",
"no-else-return": "off",
"no-empty-function": ["error", {
"allow": ["arrowFunctions", "methods", "asyncMethods"],
}],
"no-extend-native": "off",
"no-global-assign": "off",
"no-lonely-if": "off",
"no-loop-func": "off",
"no-mixed-operators": "off",
"no-mixed-spaces-and-tabs": ["error", "smart-tabs"],
"no-multi-spaces": "warn",
"no-param-reassign": "off",
"no-plusplus": "off",
"no-prototype-builtins": "off",
"no-redeclare": "off",
"no-restricted-globals": "off",
"no-restricted-syntax": "off",
"no-return-await": "off",
"no-tabs": "warn",
"no-underscore-dangle": "off",
"no-unused-vars": ["warn", {
"args": "none",
"caughtErrorsIgnorePattern": "^_",
"varsIgnorePattern": "[A-Z_]+|tr|[$]",
}],
"no-use-before-define": "off",
"no-useless-escape": "off",
"no-useless-return": "off",
"no-var": "error",
"object-curly-spacing": ["warn", "always"],
"object-shorthand": "off",
"operator-linebreak": "off",
"prefer-arrow-callback": "off",
"prefer-const": "warn",
"prefer-destructuring": "off",
"prefer-template": "off",
"quote-props": "off",
"quotes": ["error", "single", {
"avoidEscape": true,
}],
"semi": ["error", "always"],
"space-before-blocks": "warn",
"space-before-function-paren": "off",
"space-in-parens": ["error", "never"],
"space-unary-ops": "off",
"spaced-comment": "off",
"strict": "off",
"vars-on-top": "off",
},
}]);

View file

@ -189,7 +189,7 @@ const initContextMenuItems = async function() {
await keepass.reconnect(null, 5000); // 5 second timeout for the first connect
await keepass.enableAutomaticReconnect();
await keepass.updateDatabase();
} catch (e) {
} catch (_e) {
logError('init.js failed');
}
})();

View file

@ -485,7 +485,7 @@ page.getTopLevelDomainFromUrl = async function(domain, url) {
url: url
});
}
} catch (e) {
} catch (_e) {
return domain;
}
}

View file

@ -28,7 +28,7 @@ kpxcBanner.destroy = async function() {
} else {
window.parent.document.body.removeChild(window.parent.document.body.querySelector('#kpxc-banner'));
}
} catch(e) {
} catch(_e) {
kpxcBanner.wrapper.style.display = 'hidden';
}

View file

@ -33,7 +33,7 @@ kpxc.addToSitePreferences = async function(optionName, addWildcard = false) {
let site;
try {
site = trimURL(window.top.location.href);
} catch (err) {
} catch (_err) {
logDebug('Adding to Site Preferences denied from iframe.');
return;
}
@ -730,7 +730,7 @@ kpxc.siteIgnored = async function(condition) {
let currentLocation;
try {
currentLocation = window.top.location.href;
} catch (err) {
} catch (_err) {
// Cross-domain security error inspecting window.top.location.href.
// This catches an error when an iframe is being accessed from another (sub)domain
// -> use the iframe URL instead.
@ -998,7 +998,7 @@ const isIframeAllowed = async function() {
// Check for Cross-domain security error when inspecting window.top.location.href
const currentLocation = window.top.location.href;
return true;
} catch (err) {
} catch (_err) {
// Inspect iframe using TLD and the tab's original URL
const allowed = await sendMessage('is_iframe_allowed', [ window.location.href, window.location.hostname ]);
if (allowed) {

View file

@ -328,7 +328,7 @@ const getShadowDOM = function(elem) {
try {
return elem.openOrClosedShadowRoot ? elem.openOrClosedShadowRoot : browser.dom.openOrClosedShadowRoot(elem);
} catch (e) {
} catch (_e) {
return elem.shadowRoot;
}
};

View file

@ -140,7 +140,7 @@
const isSameOriginWithAncestors = function() {
try {
return window.self.origin === window.top.origin;
} catch (err) {
} catch (_err) {
return false;
}
};

View file

@ -341,7 +341,7 @@ kpxcUI.createNotification = function(type, message) {
let parentBody;
try {
parentBody = window.parent.document.body;
} catch(e) {
} catch(_e) {
parentBody = window.document.body;
}

View file

@ -287,7 +287,7 @@ options.initGeneralSettings = async function() {
// Verify the import
temporarySettings = contents;
dialogImportSettingsModal.show();
} catch (err) {
} catch (_err) {
console.log('Error loading JSON settings file.');
}
};

1142
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -4,9 +4,10 @@
"description": "KeePassXC-Browser",
"main": "build.js",
"devDependencies": {
"@eslint/js": "^9.39.1",
"@playwright/test": "^1.56.1",
"@types/node": "^20.14.10",
"eslint": "^8.49.0"
"eslint": "^9.39.1"
},
"dependencies": {
"@npmcli/fs": "^2.1.0"
@ -15,7 +16,7 @@
"build": "node build.js",
"debug:chromium": "cp dist/manifest_chromium.json keepassxc-browser/manifest.json",
"debug:firefox": "cp dist/manifest_firefox.json keepassxc-browser/manifest.json",
"lint": "npx eslint keepassxc-browser/**/*.js",
"lint": "npx eslint --no-warn-ignored keepassxc-browser/**/*.js",
"tests": "npx playwright test"
},
"repository": {

View file

@ -1,8 +0,0 @@
{
"env": {
"node": true
},
"parserOptions": {
"sourceType": "module"
}
}