Compare commits

..

4 Commits

Author SHA1 Message Date
fiatjaf
0235b490fa nip27: fix trailing / in urls. 2025-12-11 21:23:32 -03:00
fiatjaf
e290f98a86 label forced ping subscription. 2025-12-10 21:06:31 -03:00
fiatjaf
7a50d9328d add some more kinds. 2025-12-09 10:56:43 -03:00
fiatjaf
65412e5b85 NostrEvent > Event. 2025-12-06 12:21:56 -03:00
7 changed files with 53 additions and 7 deletions

View File

@@ -219,6 +219,7 @@ export class AbstractRelay {
const sub = this.subscribe( const sub = this.subscribe(
[{ ids: ['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'], limit: 0 }], [{ ids: ['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'], limit: 0 }],
{ {
label: 'forced-ping',
oneose: () => { oneose: () => {
resolve(true) resolve(true)
sub.close() sub.close()

View File

@@ -8,7 +8,7 @@ export interface Nostr {
/** Designates a verified event signature. */ /** Designates a verified event signature. */
export const verifiedSymbol = Symbol('verified') export const verifiedSymbol = Symbol('verified')
export interface Event { export type NostrEvent = {
kind: number kind: number
tags: string[][] tags: string[][]
content: string content: string
@@ -19,7 +19,7 @@ export interface Event {
[verifiedSymbol]?: boolean [verifiedSymbol]?: boolean
} }
export type NostrEvent = Event export type Event = NostrEvent
export type EventTemplate = Pick<Event, 'kind' | 'tags' | 'content' | 'created_at'> export type EventTemplate = Pick<Event, 'kind' | 'tags' | 'content' | 'created_at'>
export type UnsignedEvent = Pick<Event, 'kind' | 'tags' | 'content' | 'created_at' | 'pubkey'> export type UnsignedEvent = Pick<Event, 'kind' | 'tags' | 'content' | 'created_at' | 'pubkey'>

View File

@@ -1,6 +1,6 @@
{ {
"name": "@nostr/tools", "name": "@nostr/tools",
"version": "2.19.2", "version": "2.19.4",
"exports": { "exports": {
".": "./index.ts", ".": "./index.ts",
"./core": "./core.ts", "./core": "./core.ts",

View File

@@ -55,12 +55,24 @@ export const Reaction = 7
export type Reaction = typeof Reaction export type Reaction = typeof Reaction
export const BadgeAward = 8 export const BadgeAward = 8
export type BadgeAward = typeof BadgeAward export type BadgeAward = typeof BadgeAward
export const ChatMessage = 9
export type ChatMessage = typeof ChatMessage
export const ForumThread = 11
export type ForumThread = typeof ForumThread
export const Seal = 13 export const Seal = 13
export type Seal = typeof Seal export type Seal = typeof Seal
export const PrivateDirectMessage = 14 export const PrivateDirectMessage = 14
export type PrivateDirectMessage = typeof PrivateDirectMessage export type PrivateDirectMessage = typeof PrivateDirectMessage
export const FileMessage = 15
export type FileMessage = typeof FileMessage
export const GenericRepost = 16 export const GenericRepost = 16
export type GenericRepost = typeof GenericRepost export type GenericRepost = typeof GenericRepost
export const Photo = 20
export type Photo = typeof Photo
export const NormalVideo = 21
export type NormalVideo = typeof NormalVideo
export const ShortVideo = 22
export type ShortVideo = typeof ShortVideo
export const ChannelCreation = 40 export const ChannelCreation = 40
export type ChannelCreation = typeof ChannelCreation export type ChannelCreation = typeof ChannelCreation
export const ChannelMetadata = 41 export const ChannelMetadata = 41
@@ -75,10 +87,18 @@ export const OpenTimestamps = 1040
export type OpenTimestamps = typeof OpenTimestamps export type OpenTimestamps = typeof OpenTimestamps
export const GiftWrap = 1059 export const GiftWrap = 1059
export type GiftWrap = typeof GiftWrap export type GiftWrap = typeof GiftWrap
export const Poll = 1068
export type Poll = typeof Poll
export const FileMetadata = 1063 export const FileMetadata = 1063
export type FileMetadata = typeof FileMetadata export type FileMetadata = typeof FileMetadata
export const Comment = 1111
export type Comment = typeof Comment
export const LiveChatMessage = 1311 export const LiveChatMessage = 1311
export type LiveChatMessage = typeof LiveChatMessage export type LiveChatMessage = typeof LiveChatMessage
export const Voice = 1222
export type Voice = typeof Voice
export const VoiceComment = 1244
export type VoiceComment = typeof VoiceComment
export const ProblemTracker = 1971 export const ProblemTracker = 1971
export type ProblemTracker = typeof ProblemTracker export type ProblemTracker = typeof ProblemTracker
export const Report = 1984 export const Report = 1984
@@ -103,6 +123,8 @@ export const Zap = 9735
export type Zap = typeof Zap export type Zap = typeof Zap
export const Highlights = 9802 export const Highlights = 9802
export type Highlights = typeof Highlights export type Highlights = typeof Highlights
export const PollResponse = 1018
export type PollResponse = typeof PollResponse
export const Mutelist = 10000 export const Mutelist = 10000
export type Mutelist = typeof Mutelist export type Mutelist = typeof Mutelist
export const Pinlist = 10001 export const Pinlist = 10001
@@ -119,6 +141,8 @@ export const BlockedRelaysList = 10006
export type BlockedRelaysList = typeof BlockedRelaysList export type BlockedRelaysList = typeof BlockedRelaysList
export const SearchRelaysList = 10007 export const SearchRelaysList = 10007
export type SearchRelaysList = typeof SearchRelaysList export type SearchRelaysList = typeof SearchRelaysList
export const FavoriteRelays = 10012
export type FavoriteRelays = typeof FavoriteRelays
export const InterestsList = 10015 export const InterestsList = 10015
export type InterestsList = typeof InterestsList export type InterestsList = typeof InterestsList
export const UserEmojiList = 10030 export const UserEmojiList = 10030
@@ -127,6 +151,8 @@ export const DirectMessageRelaysList = 10050
export type DirectMessageRelaysList = typeof DirectMessageRelaysList export type DirectMessageRelaysList = typeof DirectMessageRelaysList
export const FileServerPreference = 10096 export const FileServerPreference = 10096
export type FileServerPreference = typeof FileServerPreference export type FileServerPreference = typeof FileServerPreference
export const BlossomServerList = 10063
export type BlossomServerList = typeof BlossomServerList
export const NWCWalletInfo = 13194 export const NWCWalletInfo = 13194
export type NWCWalletInfo = typeof NWCWalletInfo export type NWCWalletInfo = typeof NWCWalletInfo
export const LightningPubRPC = 21000 export const LightningPubRPC = 21000
@@ -185,9 +211,13 @@ export const Calendar = 31924
export type Calendar = typeof Calendar export type Calendar = typeof Calendar
export const CalendarEventRSVP = 31925 export const CalendarEventRSVP = 31925
export type CalendarEventRSVP = typeof CalendarEventRSVP export type CalendarEventRSVP = typeof CalendarEventRSVP
export const RelayReview = 31987
export type RelayReview = typeof RelayReview
export const Handlerrecommendation = 31989 export const Handlerrecommendation = 31989
export type Handlerrecommendation = typeof Handlerrecommendation export type Handlerrecommendation = typeof Handlerrecommendation
export const Handlerinformation = 31990 export const Handlerinformation = 31990
export type Handlerinformation = typeof Handlerinformation export type Handlerinformation = typeof Handlerinformation
export const CommunityDefinition = 34550 export const CommunityDefinition = 34550
export type CommunityDefinition = typeof CommunityDefinition export type CommunityDefinition = typeof CommunityDefinition
export const GroupMetadata = 39000
export type GroupMetadata = typeof GroupMetadata

View File

@@ -16,14 +16,14 @@ test('first: parse simple content with 1 url and 1 nostr uri', () => {
}) })
test('second: parse content with 3 urls of different types', () => { test('second: parse content with 3 urls of different types', () => {
const content = `:wss://oa.ao; this was a relay and now here's a video -> https://videos.com/video.mp4! and some music: const content = `:wss://oa.ao/a/; this was a relay and now here's a video -> https://videos.com/video.mp4! and some music:
http://music.com/song.mp3 http://music.com/song.mp3
and a regular link: https://regular.com/page?ok=true. and now a broken link: https://kjxkxk and a broken nostr ref: nostr:nevent1qqsr0f9w78uyy09qwmjt0kv63j4l7sxahq33725lqyyp79whlfjurwspz4mhxue69uhh56nzv34hxcfwv9ehw6nyddhq0ag9xg and a fake nostr ref: nostr:llll ok but finally https://ok.com!` and a regular link: https://regular.com/page?ok=true. and now a broken link: https://kjxkxk and a broken nostr ref: nostr:nevent1qqsr0f9w78uyy09qwmjt0kv63j4l7sxahq33725lqyyp79whlfjurwspz4mhxue69uhh56nzv34hxcfwv9ehw6nyddhq0ag9xg and a fake nostr ref: nostr:llll ok but finally https://ok.com!`
const blocks = Array.from(parse(content)) const blocks = Array.from(parse(content))
expect(blocks).toEqual([ expect(blocks).toEqual([
{ type: 'text', text: ':' }, { type: 'text', text: ':' },
{ type: 'relay', url: 'wss://oa.ao/' }, { type: 'relay', url: 'wss://oa.ao/a/' },
{ type: 'text', text: "; this was a relay and now here's a video -> " }, { type: 'text', text: "; this was a relay and now here's a video -> " },
{ type: 'video', url: 'https://videos.com/video.mp4' }, { type: 'video', url: 'https://videos.com/video.mp4' },
{ type: 'text', text: '! and some music:\n' }, { type: 'text', text: '! and some music:\n' },
@@ -113,3 +113,18 @@ test('emoji shortcodes are treated as text if no event tags', () => {
expect(blocks).toEqual([{ type: 'text', text: 'hello :alpaca:' }]) expect(blocks).toEqual([{ type: 'text', text: 'hello :alpaca:' }])
}) })
test("a thing that didn't work well in the wild", () => {
const blocks = Array.from(
parse(
`Crowdsourcing doesn't mean just users clicking, by the way (although that could be possible too), it means a bunch of machines competing: https://leaderboard.sbstats.uk/`,
),
)
expect(blocks).toEqual([
{
type: 'text',
text: `Crowdsourcing doesn't mean just users clicking, by the way (although that could be possible too), it means a bunch of machines competing: `,
},
{ type: 'url', url: 'https://leaderboard.sbstats.uk/' },
])
})

View File

@@ -41,7 +41,7 @@ export type Block =
} }
const noCharacter = /\W/m const noCharacter = /\W/m
const noURLCharacter = /\W |\W$|$|,| /m const noURLCharacter = /[^\w\/] |[^\w\/]$|$|,| /m
const MAX_HASHTAG_LENGTH = 42 const MAX_HASHTAG_LENGTH = 42
export function* parse(content: string | NostrEvent): Iterable<Block> { export function* parse(content: string | NostrEvent): Iterable<Block> {

View File

@@ -1,7 +1,7 @@
{ {
"type": "module", "type": "module",
"name": "nostr-tools", "name": "nostr-tools",
"version": "2.19.2", "version": "2.19.4",
"description": "Tools for making a Nostr client.", "description": "Tools for making a Nostr client.",
"repository": { "repository": {
"type": "git", "type": "git",