Validate url in fetch, rework some hints

This commit is contained in:
Jon Staab
2025-08-05 17:23:34 -07:00
parent 2edbd44f64
commit 3b4fe0973d
17 changed files with 64 additions and 36 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "@welshman", "name": "@welshman",
"private": true, "private": true,
"version": "0.4.1", "version": "0.4.2",
"workspaces": [ "workspaces": [
"packages/*" "packages/*"
], ],
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@welshman/app", "name": "@welshman/app",
"version": "0.4.1", "version": "0.4.2",
"author": "hodlbod", "author": "hodlbod",
"license": "MIT", "license": "MIT",
"description": "A collection of svelte stores for use in building nostr client applications.", "description": "A collection of svelte stores for use in building nostr client applications.",
+22
View File
@@ -0,0 +1,22 @@
import {INBOX_RELAYS, asDecryptedEvent, readList} from "@welshman/util"
import {TrustedEvent, PublishedList} from "@welshman/util"
import {deriveEventsMapped, collection} from "@welshman/store"
import {repository} from "./core.js"
import {makeOutboxLoader} from "./relaySelections.js"
export const inboxRelaySelections = deriveEventsMapped<PublishedList>(repository, {
filters: [{kinds: [INBOX_RELAYS]}],
itemToEvent: item => item.event,
eventToItem: (event: TrustedEvent) => readList(asDecryptedEvent(event)),
})
export const {
indexStore: inboxRelaySelectionsByPubkey,
deriveItem: deriveInboxRelaySelections,
loadItem: loadInboxRelaySelections,
} = collection({
name: "inboxRelaySelections",
store: inboxRelaySelections,
getKey: inboxRelaySelections => inboxRelaySelections.event.pubkey,
load: makeOutboxLoader(INBOX_RELAYS),
})
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@welshman/content", "name": "@welshman/content",
"version": "0.4.1", "version": "0.4.2",
"author": "hodlbod", "author": "hodlbod",
"license": "MIT", "license": "MIT",
"description": "A collection of utilities for parsing nostr note content.", "description": "A collection of utilities for parsing nostr note content.",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@welshman/editor", "name": "@welshman/editor",
"version": "0.4.1", "version": "0.4.2",
"author": "hodlbod", "author": "hodlbod",
"license": "MIT", "license": "MIT",
"description": "A batteries-included nostr editor.", "description": "A batteries-included nostr editor.",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@welshman/feeds", "name": "@welshman/feeds",
"version": "0.4.1", "version": "0.4.2",
"author": "hodlbod", "author": "hodlbod",
"license": "MIT", "license": "MIT",
"description": "Utilities for building dynamic nostr feeds.", "description": "Utilities for building dynamic nostr feeds.",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@welshman/lib", "name": "@welshman/lib",
"version": "0.4.1", "version": "0.4.2",
"author": "hodlbod", "author": "hodlbod",
"license": "MIT", "license": "MIT",
"description": "A collection of utilities.", "description": "A collection of utilities.",
+3
View File
@@ -1291,6 +1291,9 @@ type FetchOpts = {
* @returns Promise of parsed JSON response * @returns Promise of parsed JSON response
*/ */
export const fetchJson = async (url: string, opts: FetchOpts = {}) => { export const fetchJson = async (url: string, opts: FetchOpts = {}) => {
// Make sure the url is valid, this will throw if not
url = String(new URL(url))
if (!opts.headers) { if (!opts.headers) {
opts.headers = {} opts.headers = {}
} }
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@welshman/net", "name": "@welshman/net",
"version": "0.4.1", "version": "0.4.2",
"author": "hodlbod", "author": "hodlbod",
"license": "MIT", "license": "MIT",
"description": "Utilities for connecting with nostr relays.", "description": "Utilities for connecting with nostr relays.",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@welshman/relay", "name": "@welshman/relay",
"version": "0.4.1", "version": "0.4.2",
"author": "hodlbod", "author": "hodlbod",
"license": "MIT", "license": "MIT",
"description": "An in-memory nostr relay implementation.", "description": "An in-memory nostr relay implementation.",
+1 -1
View File
@@ -56,7 +56,7 @@ export class Repository<E extends HashedEvent = TrustedEvent> extends Emitter {
constructor() { constructor() {
super() super()
this.setMaxListeners(100) this.setMaxListeners(1000)
} }
// Dump/load/clear // Dump/load/clear
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@welshman/router", "name": "@welshman/router",
"version": "0.4.1", "version": "0.4.2",
"author": "hodlbod", "author": "hodlbod",
"license": "MIT", "license": "MIT",
"description": "A collection of utilities for nostr relay selection.", "description": "A collection of utilities for nostr relay selection.",
+25 -22
View File
@@ -1,4 +1,5 @@
import { import {
nth,
uniq, uniq,
intersection, intersection,
mergeLeft, mergeLeft,
@@ -31,6 +32,7 @@ import {
getAncestorTags, getAncestorTags,
asDecryptedEvent, asDecryptedEvent,
getRelaysFromList, getRelaysFromList,
getPubkeyTags,
RelayMode, RelayMode,
} from "@welshman/util" } from "@welshman/util"
import {Repository} from "@welshman/relay" import {Repository} from "@welshman/relay"
@@ -212,32 +214,33 @@ export class Router {
return this.merge(scenarios) return this.merge(scenarios)
} }
EventAncestors = (event: TrustedEvent, type: "mentions" | "replies" | "roots") => { EventParents = (event: TrustedEvent) => {
const ancestorTags = getAncestorTags(event) const {replies} = getAncestorTags(event)
const mentions = getPubkeyTags(event.tags)
const authors = replies.map(nth(3)).filter(p => p?.length === 64)
const others = mentions.map(nth(1)).filter(p => p?.length === 64)
const relays = uniq([...replies, ...mentions].map(nth(2)).filter(r => r && isRelayUrl(r)))
const tags: string[][] = (ancestorTags as any)[type] || [] return this.merge([
this.FromPubkeys(authors).weight(10),
return this.scenario( this.FromPubkeys(others),
tags.flatMap(([_, value, relay, ...pubkeys]) => { this.FromRelays(relays),
const selections = [ ])
makeSelection(this.ForUser().getUrls(), 0.5),
makeSelection(this.FromPubkeys(pubkeys).getUrls()),
]
if (relay) {
selections.push(makeSelection([relay], 0.9))
}
return selections
}),
)
} }
EventMentions = (event: TrustedEvent) => this.EventAncestors(event, "mentions") EventRoots = (event: TrustedEvent) => {
const {roots} = getAncestorTags(event)
const mentions = getPubkeyTags(event.tags)
const authors = roots.map(nth(3)).filter(p => p?.length === 64)
const others = mentions.map(nth(1)).filter(p => p?.length === 64)
const relays = uniq([...roots, ...mentions].map(nth(2)).filter(r => r && isRelayUrl(r)))
EventParents = (event: TrustedEvent) => this.EventAncestors(event, "replies") return this.merge([
this.FromPubkeys(authors).weight(10),
EventRoots = (event: TrustedEvent) => this.EventAncestors(event, "roots") this.FromPubkeys(others),
this.FromRelays(relays),
])
}
PublishEvent = (event: TrustedEvent) => { PublishEvent = (event: TrustedEvent) => {
const pubkeys = getPubkeyTagValues(event.tags) const pubkeys = getPubkeyTagValues(event.tags)
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@welshman/signer", "name": "@welshman/signer",
"version": "0.4.1", "version": "0.4.2",
"author": "hodlbod", "author": "hodlbod",
"license": "MIT", "license": "MIT",
"description": "A nostr signer implemenation supporting several login methods.", "description": "A nostr signer implemenation supporting several login methods.",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@welshman/store", "name": "@welshman/store",
"version": "0.4.1", "version": "0.4.2",
"author": "hodlbod", "author": "hodlbod",
"license": "MIT", "license": "MIT",
"description": "A collection of utilities based on svelte/store for use with welshman", "description": "A collection of utilities based on svelte/store for use with welshman",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@welshman/util", "name": "@welshman/util",
"version": "0.4.1", "version": "0.4.2",
"author": "hodlbod", "author": "hodlbod",
"license": "MIT", "license": "MIT",
"description": "A collection of nostr-related utilities.", "description": "A collection of nostr-related utilities.",
+1 -1
View File
@@ -2,4 +2,4 @@
set -e set -e
# Run the TypeScript script using ts-node # Run the TypeScript script using ts-node
pnpm exec ts-node scripts/apply_version.ts pnpm exec ts-node scripts/bump.ts