5 changed files with 92 additions and 19 deletions
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
import { kinds } from 'nostr-tools' |
||||
import { ExtendedKind } from '@/constants' |
||||
import { |
||||
filterPublishingRelayUrls, |
||||
filterRelayUrlsForSocialKindPublish, |
||||
isSocialKindBlockedRelayUrl |
||||
} from '@/lib/social-kind-blocked-relays' |
||||
import { describe, expect, it } from 'vitest' |
||||
|
||||
describe('social-kind-blocked-relays', () => { |
||||
it('matches essayist by hostname even with a path suffix', () => { |
||||
expect(isSocialKindBlockedRelayUrl('wss://essayist.decentnewsroom.com/')).toBe(true) |
||||
expect(isSocialKindBlockedRelayUrl('wss://essayist.decentnewsroom.com/npub1abc')).toBe(true) |
||||
}) |
||||
|
||||
it('strips essayist for kind 1 and reactions but not long-form', () => { |
||||
const urls = ['wss://relay.damus.io/', 'wss://essayist.decentnewsroom.com/'] |
||||
expect(filterRelayUrlsForSocialKindPublish(urls, kinds.ShortTextNote)).toEqual([ |
||||
'wss://relay.damus.io/' |
||||
]) |
||||
expect(filterRelayUrlsForSocialKindPublish(urls, kinds.Reaction)).toEqual([ |
||||
'wss://relay.damus.io/' |
||||
]) |
||||
expect(filterRelayUrlsForSocialKindPublish(urls, kinds.LongFormArticle)).toEqual(urls) |
||||
}) |
||||
|
||||
it('filterPublishingRelayUrls applies read-only and social filters', () => { |
||||
const out = filterPublishingRelayUrls( |
||||
['wss://nostr.land/', 'wss://essayist.decentnewsroom.com/', 'wss://relay.damus.io/'], |
||||
ExtendedKind.COMMENT |
||||
) |
||||
expect(out).toEqual(['wss://relay.damus.io/']) |
||||
}) |
||||
}) |
||||
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
import { SOCIAL_KIND_BLOCKED_RELAY_URLS, isSocialKindBlockedKind } from '@/constants' |
||||
import { filterRelaysForEventPublish } from '@/lib/relay-publish-filter' |
||||
import { dedupeNormalizeRelayUrlsOrdered } from '@/lib/relay-url-priority' |
||||
import { normalizeRelayUrlByScheme } from '@/lib/url' |
||||
|
||||
function relayHostname(url: string): string | null { |
||||
const normalized = normalizeRelayUrlByScheme(url) || url.trim() |
||||
if (!normalized) return null |
||||
try { |
||||
return new URL(normalized).hostname.toLowerCase() |
||||
} catch { |
||||
return null |
||||
} |
||||
} |
||||
|
||||
const blockedExactKeys = new Set( |
||||
SOCIAL_KIND_BLOCKED_RELAY_URLS.map((u) => (normalizeRelayUrlByScheme(u) || u).toLowerCase()).filter(Boolean) |
||||
) |
||||
|
||||
const blockedHostnames = new Set( |
||||
SOCIAL_KIND_BLOCKED_RELAY_URLS.map((u) => relayHostname(u)).filter((h): h is string => !!h) |
||||
) |
||||
|
||||
/** True when `url` is (or is hosted on) a relay in {@link SOCIAL_KIND_BLOCKED_RELAY_URLS}. */ |
||||
export function isSocialKindBlockedRelayUrl(url: string): boolean { |
||||
const key = (normalizeRelayUrlByScheme(url) || url.trim()).toLowerCase() |
||||
if (!key) return false |
||||
if (blockedExactKeys.has(key)) return true |
||||
const host = relayHostname(url) |
||||
return host != null && blockedHostnames.has(host) |
||||
} |
||||
|
||||
/** Strip social-kind-blocked relays for kinds in {@link isSocialKindBlockedKind}. */ |
||||
export function filterRelayUrlsForSocialKindPublish( |
||||
urls: readonly string[], |
||||
eventKind: number |
||||
): string[] { |
||||
if (!isSocialKindBlockedKind(eventKind)) return [...urls] |
||||
return urls.filter((url) => !isSocialKindBlockedRelayUrl(url)) |
||||
} |
||||
|
||||
/** Read-only / profile-index filter + social-kind-blocked strip + dedupe (publish stack). */ |
||||
export function filterPublishingRelayUrls(urls: readonly string[], eventKind: number): string[] { |
||||
return dedupeNormalizeRelayUrlsOrdered( |
||||
filterRelayUrlsForSocialKindPublish(filterRelaysForEventPublish(urls, eventKind), eventKind) |
||||
) |
||||
} |
||||
Loading…
Reference in new issue