From 3eca2879ef2d1a6b9934318a9fa412049cf0b120 Mon Sep 17 00:00:00 2001 From: Gigi Date: Thu, 2 Oct 2025 11:26:12 +0200 Subject: [PATCH] fix: resolve all linting and type checking issues - Fix empty catch blocks in BookmarkItem and bookmarkService - Replace any types with proper NostrEvent interface - Add proper error handling with console.warn - Use eslint-disable for unavoidable any types in applesauce integration --- src/components/BookmarkItem.tsx | 6 +++++- src/services/bookmarkService.ts | 36 +++++++++++++++++++++++---------- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/components/BookmarkItem.tsx b/src/components/BookmarkItem.tsx index 0b46561c..23ca7fe8 100644 --- a/src/components/BookmarkItem.tsx +++ b/src/components/BookmarkItem.tsx @@ -11,7 +11,11 @@ interface BookmarkItemProps { export const BookmarkItem: React.FC = ({ bookmark, index }) => { const copy = async (text: string) => { - try { await navigator.clipboard.writeText(text) } catch {} + try { + await navigator.clipboard.writeText(text) + } catch (error) { + console.warn('Failed to copy to clipboard:', error) + } } const short = (v: string) => `${v.slice(0, 8)}...${v.slice(-8)}` diff --git a/src/services/bookmarkService.ts b/src/services/bookmarkService.ts index 4af3baa3..127122d4 100644 --- a/src/services/bookmarkService.ts +++ b/src/services/bookmarkService.ts @@ -36,14 +36,24 @@ function isHexId(id: unknown): id is string { return typeof id === 'string' && /^[0-9a-f]{64}$/i.test(id) } -function dedupeNip51Events(events: any[]): any[] { - const byId = new Map() +interface NostrEvent { + id: string + kind: number + created_at: number + tags: string[][] + content: string + pubkey: string + sig: string +} + +function dedupeNip51Events(events: NostrEvent[]): NostrEvent[] { + const byId = new Map() for (const e of events) { if (e?.id && !byId.has(e.id)) byId.set(e.id, e) } const unique = Array.from(byId.values()) const latest10003 = unique .filter(e => e.kind === 10003) .sort((a, b) => (b.created_at || 0) - (a.created_at || 0))[0] - const byD = new Map() + const byD = new Map() for (const e of unique) { if (e.kind !== 30001) continue const d = (e.tags || []).find((t: string[]) => t[0] === 'd')?.[1] || '' @@ -51,7 +61,7 @@ function dedupeNip51Events(events: any[]): any[] { if (!prev || (e.created_at || 0) > (prev.created_at || 0)) byD.set(d, e) } const sets30001 = Array.from(byD.values()) - const out: any[] = [] + const out: NostrEvent[] = [] if (latest10003) out.push(latest10003) out.push(...sets30001) return out @@ -128,7 +138,7 @@ export const fetchBookmarks = async ( return } // Aggregate across events - const maybeAccount = activeAccount as any + const maybeAccount = activeAccount as AccountWithExtension const signerCandidate = typeof maybeAccount?.signEvent === 'function' ? maybeAccount : maybeAccount?.signer const publicItemsAll: IndividualBookmark[] = [] const privateItemsAll: IndividualBookmark[] = [] @@ -147,27 +157,31 @@ export const fetchBookmarks = async ( if (Helpers.hasHiddenTags(evt) && Helpers.isHiddenTagsLocked(evt) && signerCandidate) { try { await Helpers.unlockHiddenTags(evt, signerCandidate) - } catch { + } catch (error) { + console.warn('Failed to unlock with default method, trying NIP-44:', error) + // eslint-disable-next-line @typescript-eslint/no-explicit-any await Helpers.unlockHiddenTags(evt, signerCandidate as any, 'nip44' as any) } } const priv = Helpers.getHiddenBookmarks(evt) privateItemsAll.push(...processApplesauceBookmarks(priv, activeAccount, true)) - } catch { - // ignore per-event failures + } catch (error) { + console.warn('Failed to process hidden bookmarks for event:', evt.id, error) } } const allItems = [...publicItemsAll, ...privateItemsAll] const noteIds = Array.from(new Set(allItems.map(i => i.id).filter(isHexId))) - let idToEvent: Map = new Map() + let idToEvent: Map = new Map() if (noteIds.length > 0) { try { const events = await lastValueFrom( relayPool.req(relayUrls, { ids: noteIds }).pipe(completeOnEose(), takeUntil(timer(10000)), toArray()) ) - idToEvent = new Map(events.map((e: any) => [e.id, e])) - } catch {} + idToEvent = new Map(events.map((e: NostrEvent) => [e.id, e])) + } catch (error) { + console.warn('Failed to fetch events for hydration:', error) + } } const hydrateItems = (items: IndividualBookmark[]): IndividualBookmark[] => items.map(item => { const ev = idToEvent.get(item.id)