feat(electron): support object-based electronSwitches (#4161)

Previously, `electronSwitches` only accepted strings. This PR adds
support for object entries, allowing switches with values:

```js
electronSwitches: [
  "no-sandbox",
  { "js-flags": "--max-old-space-size=8192" }
]
```

I decided to put the logic into a helper file so it can be unit-tested
independently, since electron.js itself requires a live Electron
environment and cannot be tested in isolation.

Fixes #4159
This commit is contained in:
Kristjan ESPERANTO
2026-05-20 22:30:23 +02:00
committed by GitHub
parent fd687bf5fe
commit e55b11be5d
3 changed files with 104 additions and 4 deletions

View File

@@ -3,6 +3,7 @@
const electron = require("electron");
const core = require("./app");
const Log = require("./logger");
const { applyElectronSwitches } = require("./electron_helper");
// Config
let config = process.env.config ? JSON.parse(process.env.config) : {};
@@ -43,10 +44,7 @@ function createWindow () {
Log.warn("Could not get display size, using defaults ...");
}
app.commandLine.appendSwitch("autoplay-policy", "no-user-gesture-required");
for (const electronSwitch of (config.electronSwitches || [])) {
app.commandLine.appendSwitch(electronSwitch);
}
applyElectronSwitches(app.commandLine, config.electronSwitches);
let electronOptionsDefaults = {
width: electronSize.width,
height: electronSize.height,

30
js/electron_helper.js Normal file
View File

@@ -0,0 +1,30 @@
const Log = require("./logger");
/**
* Applies Electron command-line switches from config.
* @param {object} commandLine Electron commandLine API
* @param {Array<string|object>} [electronSwitches] User-configured switches
*/
function applyElectronSwitches (commandLine, electronSwitches) {
if (electronSwitches === undefined) return;
if (!Array.isArray(electronSwitches)) {
Log.error(`electronSwitches must be an array of strings or objects, got: ${JSON.stringify(electronSwitches)}`);
return;
}
for (const sw of electronSwitches) {
if (typeof sw === "string") {
commandLine.appendSwitch(sw);
Log.debug(`Activated switch: ${sw}`);
} else if (sw && typeof sw === "object" && !Array.isArray(sw)) {
for (const [name, value] of Object.entries(sw)) {
commandLine.appendSwitch(name, String(value));
Log.debug(`Activated switch: ${name}=${value}`);
}
} else {
Log.error(`Invalid electronSwitches entry: ${JSON.stringify(sw)}`);
}
}
}
module.exports = { applyElectronSwitches };

View File

@@ -0,0 +1,72 @@
const Log = require("logger");
const { applyElectronSwitches } = require("../../../js/electron_helper");
describe("electron switches", () => {
let commandLine;
beforeEach(() => {
commandLine = {
appendSwitch: vi.fn()
};
vi.spyOn(Log, "error").mockImplementation(() => {});
});
it("does nothing when electronSwitches is undefined", () => {
applyElectronSwitches(commandLine, undefined);
expect(commandLine.appendSwitch).not.toHaveBeenCalled();
expect(Log.error).not.toHaveBeenCalled();
});
it("applies string entries as switches without values", () => {
applyElectronSwitches(commandLine, ["no-sandbox", "disable-http-cache"]);
expect(commandLine.appendSwitch).toHaveBeenCalledTimes(2);
expect(commandLine.appendSwitch).toHaveBeenNthCalledWith(1, "no-sandbox");
expect(commandLine.appendSwitch).toHaveBeenNthCalledWith(2, "disable-http-cache");
expect(Log.error).not.toHaveBeenCalled();
});
it("applies object entries as switches with values", () => {
applyElectronSwitches(commandLine, [
{ "js-flags": "--max-old-space-size=8192" },
{ "password-store": "basic" }
]);
expect(commandLine.appendSwitch).toHaveBeenCalledTimes(2);
expect(commandLine.appendSwitch).toHaveBeenNthCalledWith(1, "js-flags", "--max-old-space-size=8192");
expect(commandLine.appendSwitch).toHaveBeenNthCalledWith(2, "password-store", "basic");
expect(Log.error).not.toHaveBeenCalled();
});
it("allows one object entry to define multiple switches with values", () => {
applyElectronSwitches(commandLine, [
"no-sandbox",
{
"js-flags": "--max-old-space-size=8192",
"password-store": "basic"
}
]);
expect(commandLine.appendSwitch).toHaveBeenCalledTimes(3);
expect(commandLine.appendSwitch).toHaveBeenNthCalledWith(1, "no-sandbox");
expect(commandLine.appendSwitch).toHaveBeenNthCalledWith(2, "js-flags", "--max-old-space-size=8192");
expect(commandLine.appendSwitch).toHaveBeenNthCalledWith(3, "password-store", "basic");
expect(Log.error).not.toHaveBeenCalled();
});
it("logs an error for invalid entries", () => {
applyElectronSwitches(commandLine, ["no-sandbox", ["js-flags", "--max-old-space-size=8192"], null]);
expect(commandLine.appendSwitch).toHaveBeenCalledTimes(1);
expect(commandLine.appendSwitch).toHaveBeenCalledWith("no-sandbox");
expect(Log.error).toHaveBeenCalledTimes(2);
});
it("logs an error when electronSwitches is not an array", () => {
applyElectronSwitches(commandLine, { "js-flags": "--max-old-space-size=8192" });
expect(commandLine.appendSwitch).not.toHaveBeenCalled();
expect(Log.error).toHaveBeenCalledWith(expect.stringContaining("electronSwitches must be an array of strings or objects"));
});
});