refactor: enable ESLint rule "no-unused-vars" and handle related issues (#4080)

In PR #4072 GitHub Bot complained about an unused var. Instead of just
removing that one, I checked why ESLint hadn't complained about it: We
had disabled the rule for it.

So I enabled rule and resolved the issues that ESLint then detected.

Related to #4073
This commit is contained in:
Kristjan ESPERANTO
2026-04-02 08:56:27 +02:00
committed by GitHub
parent 32aa5c8721
commit 8e1630e8bf
28 changed files with 38 additions and 37 deletions

View File

@@ -167,7 +167,7 @@ Module.register("calendar", {
this.selfUpdate();
},
notificationReceived (notification, payload, sender) {
notificationReceived (notification, payload) {
if (notification === "FETCH_CALENDAR") {
this.sendSocketNotification(notification, { url: payload.url, id: this.identifier });
}

View File

@@ -1,6 +1,5 @@
const ical = require("node-ical");
const Log = require("logger");
const { Agent } = require("undici");
const CalendarFetcherUtils = require("./calendarfetcherutils");
const HTTPFetcher = require("#http_fetcher");

View File

@@ -62,7 +62,7 @@ const CalendarFetcherUtils = {
// Subtract 1 second so that events that start on the middle of the night will not repeat.
.subtract(1, "seconds");
Object.entries(data).forEach(([key, event]) => {
Object.values(data).forEach((event) => {
if (event.type !== "VEVENT") {
return;
}

View File

@@ -308,7 +308,7 @@ Module.register("compliments", {
},
// Override notification handler.
notificationReceived (notification, payload, sender) {
notificationReceived (notification, payload) {
if (notification === "CURRENTWEATHER_TYPE") {
this.currentWeatherType = payload.type;
}

View File

@@ -411,7 +411,7 @@ Module.register("newsfeed", {
}
},
notificationReceived (notification, payload, sender) {
notificationReceived (notification) {
const before = this.activeItem;
if (notification === "MODULE_DOM_CREATED" && this.config.hideLoading) {
this.hide();

View File

@@ -51,7 +51,7 @@ class GitHelper {
// Folder has .git and has at least one git remote, watch this folder
this.gitRepos.push({ module: moduleName, folder: moduleFolder });
}
} catch (err) {
} catch {
// Error when directory .git doesn't exist or doesn't have any remotes
// This module is not managed with git, skip
}

View File

@@ -113,7 +113,7 @@ class Updater {
Log.info(`Updating ${module.name}...`);
return new Promise((resolve) => {
Exec(Command, { cwd: modulePath, timeout: this.timeout }, (error, stdout, stderr) => {
Exec(Command, { cwd: modulePath, timeout: this.timeout }, (error, stdout) => {
if (error) {
Log.error(`exec error: ${error}`);
Result.error = true;
@@ -143,7 +143,7 @@ class Updater {
pm2Restart () {
Log.info("[PM2] restarting MagicMirror...");
const pm2 = require("pm2");
pm2.restart(this.PM2Id, (err, proc) => {
pm2.restart(this.PM2Id, (err) => {
if (err) {
Log.error("[PM2] restart Error", err);
}

View File

@@ -314,7 +314,7 @@ class YrProvider {
// Convert collected data to forecast objects
const days = [];
for (const [dateStr, data] of dailyData) {
for (const data of dailyData.values()) {
const stellarInfo = this.#getStellarInfoForDate(data.date);
const dayData = {

View File

@@ -1,4 +1,4 @@
/* global WeatherProvider, WeatherUtils, WeatherObject, formatTime */
/* global WeatherUtils, WeatherObject, formatTime */
Module.register("weather", {
// Default module config.

View File

@@ -68,7 +68,6 @@ export default defineConfig([
"no-throw-literal": "error",
"no-undefined": "off",
"no-unneeded-ternary": "error",
"no-unused-vars": "off",
"no-useless-return": "error",
"no-warning-comments": "off",
"object-shorthand": ["error", "methods"],

View File

@@ -1,4 +1,5 @@
/* enumeration of animations in Array **/
const AnimateCSSIn = [
// Attention seekers
"bounce",
@@ -155,4 +156,4 @@ function removeAnimateCSS (element, animation) {
node.classList.remove("animate__animated", animationName);
node.style.removeProperty("--animate-duration");
}
if (typeof window === "undefined") module.exports = { AnimateCSSIn, AnimateCSSOut };
if (typeof window === "undefined") module.exports = { AnimateCSSIn, AnimateCSSOut, addAnimateCSS, removeAnimateCSS };

View File

@@ -84,7 +84,7 @@ function App () {
try {
fs.accessSync(moduleFile, fs.constants.R_OK);
} catch (e) {
} catch {
Log.warn(`No ${moduleFile} found for module: ${moduleName}.`);
}
@@ -93,7 +93,7 @@ function App () {
let loadHelper = true;
try {
fs.accessSync(helperPath, fs.constants.R_OK);
} catch (e) {
} catch {
loadHelper = false;
Log.log(`No helper found for module: ${moduleName}.`);
}
@@ -188,7 +188,7 @@ function App () {
try {
fs.renameSync(`${global.root_path}/css/custom.css`, `${global.root_path}/${env.customCss}`);
Log.warn(`WARNING! Your custom css file was moved from ${global.root_path}/css/custom.css to ${global.root_path}/${env.customCss}`);
} catch (err) {
} catch {
Log.warn("WARNING! Your custom css file is currently located in the css folder. Please move it to the config folder!");
}
}

View File

@@ -115,7 +115,7 @@ function createWindow () {
}
// simulate mouse move to hide black cursor on start
mainWindow.webContents.on("dom-ready", (event) => {
mainWindow.webContents.on("dom-ready", () => {
mainWindow.webContents.sendInputEvent({ type: "mouseMove", x: 0, y: 0 });
});

View File

@@ -300,7 +300,7 @@ class HTTPFetcher extends EventEmitter {
try {
const urlObj = new URL(this.url);
shortUrl = `${urlObj.origin}${urlObj.pathname}${urlObj.search.length > 50 ? "?..." : urlObj.search}`;
} catch (urlError) {
} catch {
// If URL parsing fails, use original URL
}

View File

@@ -22,12 +22,12 @@ function isAllowed (clientIp, whitelist) {
// Single IP address - let ipaddr.process normalize both
const allowedAddr = ipaddr.process(entry);
return addr.toString() === allowedAddr.toString();
} catch (err) {
} catch {
Log.warn(`Invalid whitelist entry: ${entry}`);
return false;
}
});
} catch (err) {
} catch {
Log.warn(`Failed to parse client IP: ${clientIp}`);
return false;
}

View File

@@ -1,5 +1,6 @@
/* global defaultModules, vendor */
// eslint-disable-next-line no-unused-vars
const Loader = (function () {
/* Create helper variables */

View File

@@ -29,7 +29,7 @@
return styleText("gray", parentDir === "js" ? `[${baseName}]` : `[${parentDir}]`);
}
}
} catch (err) { /* ignore */ }
} catch { /* ignore */ }
return styleText("gray", "[unknown]");
};

View File

@@ -1,4 +1,4 @@
/* global Loader, defaults, addAnimateCSS, removeAnimateCSS, AnimateCSSIn, AnimateCSSOut, modulePositions, io */
/* global Loader, addAnimateCSS, removeAnimateCSS, AnimateCSSIn, AnimateCSSOut, modulePositions, io */
const MM = (function () {
let modules = [];
@@ -408,7 +408,7 @@ const MM = (function () {
updateWrapperStates();
// Waiting for DOM-changes done in updateWrapperStates before we can start the animation.
const dummy = moduleWrapper.parentElement.parentElement.offsetHeight;
void moduleWrapper.parentElement.parentElement.offsetHeight;
moduleWrapper.style.opacity = 1;
if (haveAnimateName) {

View File

@@ -98,7 +98,7 @@ function Server (configObj) {
}
let directories = ["/config", "/css", "/favicon.svg", "/defaultmodules", "/modules", "/node_modules/animate.css", "/node_modules/@fontsource", "/node_modules/@fortawesome", "/translations", "/tests/configs", "/tests/mocks"];
for (const [key, value] of Object.entries(vendor)) {
for (const value of Object.values(vendor)) {
const dirArr = value.split("/");
if (dirArr[0] === "node_modules") directories.push(`/${dirArr[0]}/${dirArr[1]}`);
}

View File

@@ -1,5 +1,6 @@
/* global io */
// eslint-disable-next-line no-unused-vars
const MMSocket = function (moduleName) {
if (typeof moduleName !== "string") {
throw new Error("Please set the module name for the MMSocket.");

View File

@@ -17,7 +17,7 @@ const Translator = (function () {
throw new Error(`Unexpected response status: ${response.status}`);
}
return await response.json();
} catch (exception) {
} catch {
Log.error(`Loading json file =${file} failed`);
return null;
}

View File

@@ -55,7 +55,7 @@ const getModulePositions = () => {
try {
fs.writeFileSync(discoveredPositionsJSFilename, `const modulePositions=${JSON.stringify(modulePositions)}`);
}
catch (error) {
catch {
Log.error("unable to write js/positions.js with the discovered module positions\nmake the MagicMirror/js folder writeable by the user starting MagicMirror");
}
}
@@ -111,7 +111,7 @@ const loadConfig = () => {
try {
fs.accessSync(templateFile, fs.constants.F_OK);
Log.warn("config.js.template files are deprecated and not used anymore. You can use variables inside config.js so copy the template file content into config.js if needed.");
} catch (error) {
} catch {
// no action
}

View File

@@ -35,7 +35,7 @@ function getServerConfig () {
port: global.mmPort || config.port || 8080,
address: config.address || "localhost"
};
} catch (err) {
} catch {
serverConfig = { port: 8080, address: "localhost" };
}
@@ -248,7 +248,7 @@ try {
Log.warn(`Watch target is not a file (directories not supported): ${targetPath}`);
}
}
} catch (err) {
} catch {
// Config file might not exist or be invalid, use fallback targets
Log.warn("Could not load watchTargets from config.");
}

View File

@@ -76,7 +76,7 @@ describe("translations", () => {
it("should load translation file", async () => {
const { Translator, Module, config } = dom.window;
config.language = "en";
Translator.load = vi.fn().mockImplementation((_m, _f, _fb) => null);
Translator.load = vi.fn().mockImplementation(() => null);
Module.register("name", { getTranslations: () => translations });
const MMM = Module.create("name");
@@ -89,7 +89,7 @@ describe("translations", () => {
it("should load translation + fallback file", async () => {
const { Translator, Module } = dom.window;
Translator.load = vi.fn().mockImplementation((_m, _f, _fb) => null);
Translator.load = vi.fn().mockImplementation(() => null);
Module.register("name", { getTranslations: () => translations });
const MMM = Module.create("name");
@@ -104,7 +104,7 @@ describe("translations", () => {
it("should load translation fallback file", async () => {
const { Translator, Module, config } = dom.window;
config.language = "--";
Translator.load = vi.fn().mockImplementation((_m, _f, _fb) => null);
Translator.load = vi.fn().mockImplementation(() => null);
Module.register("name", { getTranslations: () => translations });
const MMM = Module.create("name");

View File

@@ -70,7 +70,7 @@ exports.stopApplication = async (timeout = 10000) => {
if (electronProcess && !electronProcess.killed) {
electronProcess.kill("SIGKILL");
}
} catch (error) {
} catch {
// Ignore errors caused by Playwright already tearing down the connection
}
};
@@ -80,7 +80,7 @@ exports.stopApplication = async (timeout = 10000) => {
app.close(),
new Promise((_, reject) => setTimeout(() => reject(new Error("Electron close timeout")), timeout))
]);
} catch (error) {
} catch {
killElectron();
}
};

View File

@@ -26,6 +26,7 @@ describe("Calendar module", () => {
* Use this for debugging broken tests, it will console log the text of the calendar module
* @returns {Promise<void>}
*/
// eslint-disable-next-line no-unused-vars
const logAllText = async () => {
expect(global.page).not.toBeNull();
const loc = await global.page.locator(".calendar .event");

View File

@@ -42,9 +42,9 @@ Module.register("testNotification", {
let tableRow = document.createElement("tr");
table.appendChild(tableRow);
let tablecol1 = this.maketd(tableRow, col1);
let tablecol2 = this.maketd(tableRow, col2);
let tablecol3 = this.maketd(tableRow, col3);
this.maketd(tableRow, col1);
this.maketd(tableRow, col2);
this.maketd(tableRow, col3);
return tableRow;
},

View File

@@ -15,7 +15,6 @@ import { describe, it, expect, vi, beforeAll, beforeEach, afterAll, afterEach }
import yrData from "../../../../../mocks/weather_yr.json" with { type: "json" };
const YR_FORECAST_URL = "https://api.met.no/weatherapi/locationforecast/**";
const YR_SUNRISE_URL = "https://api.met.no/weatherapi/sunrise/**";
// Fixed time: 30 minutes after the first timeseries entry (2026-02-06T21:00:00Z)
// This ensures timeseries[0] is always chosen as the closest past entry.