Add PDF archive store, raw-body IPC and export file helpers

The searchable PDF can be archived content-addressed under the local data
dir with its sha256 and layout fingerprint; a different PDF for an archived
invoice is refused and reads verify the hash. Export writes go through a
raw-body command that remembers the last folder; reveal-in-folder and open
fall back to xdg-open / explorer. Adds a Windows-safe export file name
builder. Migration M4 adds the archive columns and last export dir.
This commit is contained in:
2026-10-04 05:54:26 +05:30
parent cedf4839bd
commit 7162dac6e7
17 changed files with 891 additions and 36 deletions
+1 -8
View File
@@ -10,13 +10,6 @@ import { imageSizeFromDataUri } from "./imageSize";
import { getRenderClient, nextRenderJobId } from "./renderClient";
import type { BankAccount, Invoice, Settings } from "./types";
function bytesToBase64(bytes: Uint8Array): string {
let bin = "";
const step = 0x8000;
for (let i = 0; i < bytes.length; i += step) bin += String.fromCharCode(...bytes.subarray(i, i + step));
return btoa(bin);
}
/** A logo with no readable size is fitted as if it filled Classic's 170 x 54 box. */
const UNKNOWN_LOGO_SIZE = { width: 170, height: 54 };
@@ -82,7 +75,7 @@ export async function savePdfBytes(bytes: Uint8Array, fileName: string): Promise
filters: [{ name: "PDF document", extensions: ["pdf"] }],
});
if (!path) return null;
await api.saveBinaryFile(path, bytesToBase64(bytes));
await api.writeExportFile(path, bytes);
return path;
}