diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a5f228..299e5ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,18 @@ All notable changes to Multi-Debrid Downloader are documented in this file. +## [2.0.35] - 2026-08-13 + +### Settings reliability + +- Accepted omitted optional values inside nested account status records when saving a complete settings draft. +- Prevented valid Debrid-Link and Mega-Debrid account states from triggering an invalid settings payload after account checks or provider changes. + +### Release validation + +- Added a full renderer-settings regression fixture with a checked Debrid-Link account and an omitted optional e-mail field. +- Verified account toggle sequencing, renderer settings validation, and the packaged main-process build. + ## [2.0.34] - 2026-08-13 ### Account recovery and rotation diff --git a/package-lock.json b/package-lock.json index e0118fe..3f0b6a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "real-debrid-downloader", - "version": "2.0.34", + "version": "2.0.35", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "real-debrid-downloader", - "version": "2.0.34", + "version": "2.0.35", "license": "MIT", "dependencies": { "adm-zip": "0.6.0", diff --git a/package.json b/package.json index fb00ac2..4527fe0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "real-debrid-downloader", - "version": "2.0.34", + "version": "2.0.35", "description": "Desktop downloader", "main": "build/main/main/main.js", "author": "Sucukdeluxe", diff --git a/src/main/renderer-settings.ts b/src/main/renderer-settings.ts index f027fcd..ac219b5 100644 --- a/src/main/renderer-settings.ts +++ b/src/main/renderer-settings.ts @@ -30,7 +30,11 @@ function validateJsonValue(value: unknown, depth = 0): void { } const entries = Object.entries(value as Record); if (entries.length > 10_000) invalid(); - entries.forEach(([, entry]) => validateJsonValue(entry, depth + 1)); + entries.forEach(([, entry]) => { + if (entry !== undefined) { + validateJsonValue(entry, depth + 1); + } + }); } function validateTopLevelType(value: unknown, expected: unknown): void { diff --git a/tests/renderer-settings.test.ts b/tests/renderer-settings.test.ts index 894faa2..e993f86 100644 --- a/tests/renderer-settings.test.ts +++ b/tests/renderer-settings.test.ts @@ -1,6 +1,7 @@ import { describe, expect, it } from "vitest"; import { defaultSettings } from "../src/main/constants"; import { validateRendererSettingsUpdate } from "../src/main/renderer-settings"; +import { createRendererSettings } from "../src/main/renderer-state"; describe("renderer settings validation", () => { it("ignores undefined optional fields from a stale renderer draft", () => { @@ -17,4 +18,26 @@ describe("renderer settings validation", () => { debridLinkDisabledKeyIds: [] }); }); + + it("accepts a complete renderer draft with an optional nested account status field omitted", () => { + const current = defaultSettings(); + current.debridAccountStatuses = { + "debridlink-key": { + accountId: "debridlink-key", + provider: "debridlink", + label: "Debrid-Link", + maskedLogin: "abc***xyz", + valid: true, + isPremium: true, + premiumUntilMs: null, + message: "Premium", + checkedAt: 1 + } + }; + const rendererDraft = createRendererSettings(current); + + const result = validateRendererSettingsUpdate(rendererDraft, current); + + expect(result.debridAccountStatuses).toEqual(rendererDraft.debridAccountStatuses); + }); });