feat(ext/sw): vault helpers for attachment add/remove
addAttachmentToItem appends an AttachmentRef + re-syncs the manifest entry's attachment_summaries. removeAttachmentsFromItem returns the removed refs so the caller can deleteBlob() the underlying bytes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
|
||||
import type { SessionHandle } from '../../wasm/relicario_wasm';
|
||||
import type { GitHost } from './git-host';
|
||||
import type { Item, ItemId, Manifest, ManifestEntry, VaultSettings } from '../shared/types';
|
||||
import type { AttachmentRef, Item, ItemId, Manifest, ManifestEntry, VaultSettings } from '../shared/types';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
let wasm: any = null;
|
||||
@@ -140,3 +140,83 @@ export function findByHostname(
|
||||
.filter(([, e]) => e.trashed_at === undefined)
|
||||
.filter(([, e]) => (e.icon_hint ?? '').toLowerCase() === h);
|
||||
}
|
||||
|
||||
// --- Attachment helpers ---
|
||||
|
||||
/// Sync the manifest entry's attachment_summaries for a single item.
|
||||
/// Reads the current manifest + item; if either is missing, does nothing.
|
||||
async function syncManifestAttachments(
|
||||
git: GitHost,
|
||||
handle: SessionHandle,
|
||||
itemId: ItemId,
|
||||
item: Item,
|
||||
message: string,
|
||||
): Promise<void> {
|
||||
const manifest = await fetchAndDecryptManifest(git, handle);
|
||||
const entry = manifest.items[itemId];
|
||||
if (!entry) return;
|
||||
entry.attachment_summaries = item.attachments.map((a) => ({
|
||||
id: a.id,
|
||||
filename: a.filename,
|
||||
mime_type: a.mime_type,
|
||||
size: a.size,
|
||||
}));
|
||||
await encryptAndWriteManifest(git, handle, manifest, message);
|
||||
}
|
||||
|
||||
/// Add an AttachmentRef to an existing item.
|
||||
/// Reads + decrypts the item, appends to attachments[], re-encrypts and
|
||||
/// writes both items/<id>.enc and the manifest entry's attachment_summaries.
|
||||
/// Throws if the item is not found.
|
||||
export async function addAttachmentToItem(
|
||||
git: GitHost,
|
||||
handle: SessionHandle,
|
||||
itemId: ItemId,
|
||||
ref: AttachmentRef,
|
||||
): Promise<void> {
|
||||
let item: Item;
|
||||
try {
|
||||
item = await fetchAndDecryptItem(git, handle, itemId);
|
||||
} catch {
|
||||
throw new Error(`addAttachmentToItem: item ${itemId} not found`);
|
||||
}
|
||||
item.attachments = [...item.attachments, ref];
|
||||
item.modified = Math.floor(Date.now() / 1000);
|
||||
const commitMsg = `attach ${ref.filename} to item ${itemId}`;
|
||||
await encryptAndWriteItem(git, handle, itemId, item, commitMsg);
|
||||
await syncManifestAttachments(git, handle, itemId, item, `manifest: sync attachments for ${itemId}`);
|
||||
}
|
||||
|
||||
/// Remove attachments matching the given IDs from the item.
|
||||
/// Returns the removed AttachmentRefs (so the caller can deleteBlob the
|
||||
/// underlying bytes). IDs not present in the item's attachments are
|
||||
/// silently ignored.
|
||||
export async function removeAttachmentsFromItem(
|
||||
git: GitHost,
|
||||
handle: SessionHandle,
|
||||
itemId: ItemId,
|
||||
idsToRemove: string[],
|
||||
): Promise<AttachmentRef[]> {
|
||||
let item: Item;
|
||||
try {
|
||||
item = await fetchAndDecryptItem(git, handle, itemId);
|
||||
} catch {
|
||||
throw new Error(`removeAttachmentsFromItem: item ${itemId} not found`);
|
||||
}
|
||||
const removeSet = new Set(idsToRemove);
|
||||
const removed: AttachmentRef[] = [];
|
||||
const kept: AttachmentRef[] = [];
|
||||
for (const att of item.attachments) {
|
||||
if (removeSet.has(att.id)) {
|
||||
removed.push(att);
|
||||
} else {
|
||||
kept.push(att);
|
||||
}
|
||||
}
|
||||
item.attachments = kept;
|
||||
item.modified = Math.floor(Date.now() / 1000);
|
||||
const commitMsg = `remove ${removed.length} attachment(s) from item ${itemId}`;
|
||||
await encryptAndWriteItem(git, handle, itemId, item, commitMsg);
|
||||
await syncManifestAttachments(git, handle, itemId, item, `manifest: sync attachments for ${itemId}`);
|
||||
return removed;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user