feat: :export! writes the whole diary out as a zip

There was no way to get everything out — only one entry at a time, by
hand. A diary you cannot leave is not a diary you can trust.

The archive is entries/ as one markdown file per entry named by its day,
media/ with every embedded file under its real name, and a README. Media
links are rewritten to relative paths, so the entries render in any
markdown reader with no help from this application. Names are restricted
to characters that need no escaping inside a markdown link.

It is built on the blocking pool into a temporary file and streamed, so a
diary with photographs in it never has to fit in memory.
This commit is contained in:
nvrl committed 2026-09-05 09:45:44 +02:00
1 parent 54743346fe
commit f0135d34ac
5 files changed
+314

No files matched your search

+10
View File
@@ -312,6 +312,16 @@ export const commands: CommandSpec[] = [
URL.revokeObjectURL(url)
diary.say(`wrote ${anchor.download}`)
},
bang: {
help: 'download the whole diary — every entry and every file — as a zip',
run: async () => {
// A plain navigation, so the browser streams the archive straight to
// disk instead of the tab holding all of it in memory first.
await diary.flush()
diary.say('building the archive — the download starts on its own')
location.href = '/api/export'
},
},
},
{
name: 'upload',