1
0

Standardize line endings
All checks were successful
Build & Test WASM / build-and-test (push) Successful in 1m45s

This commit is contained in:
2026-03-16 20:43:13 +01:00
parent 30def04cfa
commit 91f09b42a8
14 changed files with 2256 additions and 2230 deletions

2
.gitattributes vendored Normal file
View File

@@ -0,0 +1,2 @@
* text=auto
*.sh text eol=lf

View File

@@ -33,7 +33,7 @@ func TestIntegrationPatch(t *testing.T) {
} }
// Read patch files from the patches zip. // Read patch files from the patches zip.
patchesZipPath := "../web/public/patches/patches_4.4523646.zip" patchesZipPath := "../web/public/patches/patches_4.45.23646.zip"
patchesZip, err := os.ReadFile(patchesZipPath) patchesZip, err := os.ReadFile(patchesZipPath)
if err != nil { if err != nil {
t.Fatalf("could not read patches zip: %v", err) t.Fatalf("could not read patches zip: %v", err)

16
test.sh Executable file
View File

@@ -0,0 +1,16 @@
#!/bin/bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
echo "=== Building WASM ==="
"$SCRIPT_DIR/kobopatch-wasm/build.sh"
echo ""
echo "=== Running WASM integration test ==="
"$SCRIPT_DIR/kobopatch-wasm/test-integration.sh"
echo ""
echo "=== Running E2E tests (Playwright) ==="
cd "$SCRIPT_DIR/e2e"
npm test

View File

@@ -215,10 +215,9 @@
btnDeviceRestore.hidden = false; btnDeviceRestore.hidden = false;
showStep(stepDevice); showStep(stepDevice);
} else { } else {
deviceStatus.className = 'status-unsupported'; deviceStatus.className = 'warning';
deviceStatus.textContent = deviceStatus.textContent =
'No patches available for software version ' + info.firmware + '. ' + 'No patch available for this specific version and model combination. Currently, only Kobo Libra Colour, Kobo Clara Colour and Kobo Clara BW can be patched via this website.';
'Supported versions: ' + available.map(p => p.version).join(', ');
btnDeviceNext.hidden = true; btnDeviceNext.hidden = true;
btnDeviceRestore.hidden = true; btnDeviceRestore.hidden = true;
showStep(stepDevice); showStep(stepDevice);

View File

@@ -14,7 +14,7 @@
<main> <main>
<header class="hero"> <header class="hero">
<h1>KoboPatch <span class="hero-accent">Web UI</span> <span class="beta-pill">beta</span></h1> <h1>KoboPatch <span class="hero-accent">Web UI</span> <span class="beta-pill">beta</span></h1>
<p class="subtitle">Custom patches for your Kobo e-reader</p> <p class="subtitle">Apply patches to your Kobo Libra Colour, Kobo Clara Colour and Kobo Clara BW.</p>
</header> </header>
<!-- Step indicator --> <!-- Step indicator -->

View File

@@ -36,11 +36,6 @@ const KOBO_MODELS = {
'N204': 'Kobo Aura HD', 'N204': 'Kobo Aura HD',
}; };
/**
* Supported firmware version for patching.
*/
const SUPPORTED_FIRMWARE = '4.45.23646';
/** /**
* Firmware download URLs by version and serial prefix. * Firmware download URLs by version and serial prefix.
* Source: https://help.kobo.com/hc/en-us/articles/35059171032727 * Source: https://help.kobo.com/hc/en-us/articles/35059171032727
@@ -58,6 +53,11 @@ const FIRMWARE_DOWNLOADS = {
}, },
}; };
/**
* Supported firmware versions for patching (derived from FIRMWARE_DOWNLOADS).
*/
const SUPPORTED_FIRMWARE = Object.keys(FIRMWARE_DOWNLOADS);
/** /**
* Get the firmware download URL for a given serial prefix and firmware version. * Get the firmware download URL for a given serial prefix and firmware version.
* Returns null if no URL is available. * Returns null if no URL is available.
@@ -153,7 +153,7 @@ class KoboDevice {
? serial.substring(0, 4) ? serial.substring(0, 4)
: serial.substring(0, 3); : serial.substring(0, 3);
const model = KOBO_MODELS[serialPrefix] || 'Unknown Kobo (' + serial.substring(0, 4) + ')'; const model = KOBO_MODELS[serialPrefix] || 'Unknown Kobo (' + serial.substring(0, 4) + ')';
const isSupported = firmware === SUPPORTED_FIRMWARE; const isSupported = SUPPORTED_FIRMWARE.includes(firmware);
return { return {
serial, serial,

View File

@@ -136,14 +136,22 @@ function parsePatchConfig(configYAML) {
/** /**
* Scan the patches/ directory for available patch zips. * Scan the patches/ directory for available patch zips.
* Returns an array of { filename, version } sorted by version descending. * Returns an array of { filename, version } objects.
* Each entry in index.json may list multiple versions; these are flattened
* so that each version gets its own entry pointing to the same filename.
*/ */
async function scanAvailablePatches() { async function scanAvailablePatches() {
try { try {
const resp = await fetch('patches/index.json'); const resp = await fetch('patches/index.json');
if (!resp.ok) return []; if (!resp.ok) return [];
const list = await resp.json(); const list = await resp.json();
return list; const result = [];
for (const entry of list) {
for (const version of entry.versions) {
result.push({ filename: entry.filename, version });
}
}
return result;
} catch { } catch {
return []; return [];
} }

View File

@@ -1,6 +1,7 @@
[ [
{ {
"filename": "patches_4.4523646.zip", "filename": "patches_4.45.23646.zip",
"version": "4.45.23646" "versions": ["4.45.23646"],
} "date": "03-2026"
},
] ]