applesauce-common 0.0.0-next-20251203172109
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +59 -0
- package/dist/blueprints/app-data.d.ts +5 -0
- package/dist/blueprints/app-data.js +10 -0
- package/dist/blueprints/calendar.d.ts +5 -0
- package/dist/blueprints/calendar.js +7 -0
- package/dist/blueprints/channels.d.ts +6 -0
- package/dist/blueprints/channels.js +13 -0
- package/dist/blueprints/comment.d.ts +12 -0
- package/dist/blueprints/comment.js +15 -0
- package/dist/blueprints/delete.d.ts +9 -0
- package/dist/blueprints/delete.js +14 -0
- package/dist/blueprints/file-metadata.d.ts +8 -0
- package/dist/blueprints/file-metadata.js +11 -0
- package/dist/blueprints/follow-set.d.ts +11 -0
- package/dist/blueprints/follow-set.js +21 -0
- package/dist/blueprints/gift-wrap.d.ts +5 -0
- package/dist/blueprints/gift-wrap.js +6 -0
- package/dist/blueprints/group.d.ts +9 -0
- package/dist/blueprints/group.js +17 -0
- package/dist/blueprints/highlight.d.ts +20 -0
- package/dist/blueprints/highlight.js +12 -0
- package/dist/blueprints/index.d.ts +23 -0
- package/dist/blueprints/index.js +24 -0
- package/dist/blueprints/legacy-message.d.ts +7 -0
- package/dist/blueprints/legacy-message.js +29 -0
- package/dist/blueprints/live-stream.d.ts +6 -0
- package/dist/blueprints/live-stream.js +9 -0
- package/dist/blueprints/note.d.ts +16 -0
- package/dist/blueprints/note.js +30 -0
- package/dist/blueprints/picture-post.d.ts +12 -0
- package/dist/blueprints/picture-post.js +17 -0
- package/dist/blueprints/poll.d.ts +41 -0
- package/dist/blueprints/poll.js +33 -0
- package/dist/blueprints/profile.d.ts +3 -0
- package/dist/blueprints/profile.js +7 -0
- package/dist/blueprints/reaction.d.ts +10 -0
- package/dist/blueprints/reaction.js +14 -0
- package/dist/blueprints/share.d.ts +12 -0
- package/dist/blueprints/share.js +25 -0
- package/dist/blueprints/stream.d.ts +6 -0
- package/dist/blueprints/stream.js +7 -0
- package/dist/blueprints/torrent.d.ts +23 -0
- package/dist/blueprints/torrent.js +25 -0
- package/dist/blueprints/wrapped-message.d.ts +20 -0
- package/dist/blueprints/wrapped-message.js +64 -0
- package/dist/helpers/app-data.d.ts +39 -0
- package/dist/helpers/app-data.js +68 -0
- package/dist/helpers/app-handler.d.ts +22 -0
- package/dist/helpers/app-handler.js +67 -0
- package/dist/helpers/article.d.ts +14 -0
- package/dist/helpers/article.js +24 -0
- package/dist/helpers/blossom.d.ts +11 -0
- package/dist/helpers/blossom.js +40 -0
- package/dist/helpers/bolt11.d.ts +10 -0
- package/dist/helpers/bolt11.js +17 -0
- package/dist/helpers/bookmark.d.ts +30 -0
- package/dist/helpers/bookmark.js +96 -0
- package/dist/helpers/calendar-event.d.ts +39 -0
- package/dist/helpers/calendar-event.js +121 -0
- package/dist/helpers/calendar-rsvp.d.ts +15 -0
- package/dist/helpers/calendar-rsvp.js +38 -0
- package/dist/helpers/calendar.d.ts +6 -0
- package/dist/helpers/calendar.js +11 -0
- package/dist/helpers/channels.d.ts +13 -0
- package/dist/helpers/channels.js +27 -0
- package/dist/helpers/comment.d.ts +47 -0
- package/dist/helpers/comment.js +185 -0
- package/dist/helpers/content.d.ts +3 -0
- package/dist/helpers/content.js +8 -0
- package/dist/helpers/emoji.d.ts +21 -0
- package/dist/helpers/emoji.js +34 -0
- package/dist/helpers/encrypted-content-cache.d.ts +22 -0
- package/dist/helpers/encrypted-content-cache.js +138 -0
- package/dist/helpers/file-metadata.d.ts +55 -0
- package/dist/helpers/file-metadata.js +130 -0
- package/dist/helpers/gift-wrap.d.ts +66 -0
- package/dist/helpers/gift-wrap.js +204 -0
- package/dist/helpers/groups-helper.d.ts +6 -0
- package/dist/helpers/groups-helper.js +9 -0
- package/dist/helpers/groups.d.ts +26 -0
- package/dist/helpers/groups.js +49 -0
- package/dist/helpers/hashtag.d.ts +2 -0
- package/dist/helpers/hashtag.js +7 -0
- package/dist/helpers/highlight.d.ts +45 -0
- package/dist/helpers/highlight.js +76 -0
- package/dist/helpers/index.d.ts +37 -0
- package/dist/helpers/index.js +37 -0
- package/dist/helpers/legacy-messages.d.ts +31 -0
- package/dist/helpers/legacy-messages.js +49 -0
- package/dist/helpers/lists.d.ts +58 -0
- package/dist/helpers/lists.js +110 -0
- package/dist/helpers/lnurl.d.ts +8 -0
- package/dist/helpers/lnurl.js +44 -0
- package/dist/helpers/mailboxes.d.ts +7 -0
- package/dist/helpers/mailboxes.js +49 -0
- package/dist/helpers/messages.d.ts +31 -0
- package/dist/helpers/messages.js +57 -0
- package/dist/helpers/mute.d.ts +33 -0
- package/dist/helpers/mute.js +111 -0
- package/dist/helpers/picture-post.d.ts +5 -0
- package/dist/helpers/picture-post.js +6 -0
- package/dist/helpers/poll.d.ts +46 -0
- package/dist/helpers/poll.js +78 -0
- package/dist/helpers/reaction.d.ts +8 -0
- package/dist/helpers/reaction.js +56 -0
- package/dist/helpers/relay-discovery.d.ts +87 -0
- package/dist/helpers/relay-discovery.js +126 -0
- package/dist/helpers/reports.d.ts +28 -0
- package/dist/helpers/reports.js +38 -0
- package/dist/helpers/share.d.ts +19 -0
- package/dist/helpers/share.js +58 -0
- package/dist/helpers/stream-chat.d.ts +4 -0
- package/dist/helpers/stream-chat.js +9 -0
- package/dist/helpers/stream.d.ts +31 -0
- package/dist/helpers/stream.js +81 -0
- package/dist/helpers/threading.d.ts +55 -0
- package/dist/helpers/threading.js +94 -0
- package/dist/helpers/torrent.d.ts +55 -0
- package/dist/helpers/torrent.js +270 -0
- package/dist/helpers/user-status.d.ts +18 -0
- package/dist/helpers/user-status.js +22 -0
- package/dist/helpers/wrapped-messages.d.ts +14 -0
- package/dist/helpers/wrapped-messages.js +23 -0
- package/dist/helpers/zap.d.ts +46 -0
- package/dist/helpers/zap.js +125 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +6 -0
- package/dist/models/blossom.d.ts +11 -0
- package/dist/models/blossom.js +18 -0
- package/dist/models/bookmarks.d.ts +8 -0
- package/dist/models/bookmarks.js +24 -0
- package/dist/models/calendar.d.ts +6 -0
- package/dist/models/calendar.js +15 -0
- package/dist/models/channels.d.ts +11 -0
- package/dist/models/channels.js +61 -0
- package/dist/models/comments.d.ts +11 -0
- package/dist/models/comments.js +17 -0
- package/dist/models/gift-wrap.d.ts +7 -0
- package/dist/models/gift-wrap.js +20 -0
- package/dist/models/index.d.ts +15 -0
- package/dist/models/index.js +16 -0
- package/dist/models/legacy-messages.d.ts +14 -0
- package/dist/models/legacy-messages.js +64 -0
- package/dist/models/mutes.d.ts +16 -0
- package/dist/models/mutes.js +34 -0
- package/dist/models/pins.d.ts +4 -0
- package/dist/models/pins.js +10 -0
- package/dist/models/reactions.d.ts +11 -0
- package/dist/models/reactions.js +21 -0
- package/dist/models/thread.d.ts +33 -0
- package/dist/models/thread.js +93 -0
- package/dist/models/user-status.d.ts +11 -0
- package/dist/models/user-status.js +32 -0
- package/dist/models/wrapped-messages.d.ts +31 -0
- package/dist/models/wrapped-messages.js +76 -0
- package/dist/models/zaps.d.ts +9 -0
- package/dist/models/zaps.js +26 -0
- package/dist/operations/app-data.d.ts +6 -0
- package/dist/operations/app-data.js +21 -0
- package/dist/operations/blossom.d.ts +5 -0
- package/dist/operations/blossom.js +13 -0
- package/dist/operations/calendar-event.d.ts +34 -0
- package/dist/operations/calendar-event.js +72 -0
- package/dist/operations/calendar-rsvp.d.ts +10 -0
- package/dist/operations/calendar-rsvp.js +35 -0
- package/dist/operations/calendar.d.ts +9 -0
- package/dist/operations/calendar.js +15 -0
- package/dist/operations/channel.d.ts +4 -0
- package/dist/operations/channel.js +10 -0
- package/dist/operations/client.d.ts +4 -0
- package/dist/operations/client.js +23 -0
- package/dist/operations/comment.d.ts +4 -0
- package/dist/operations/comment.js +11 -0
- package/dist/operations/file-metadata.d.ts +4 -0
- package/dist/operations/file-metadata.js +21 -0
- package/dist/operations/geohash.d.ts +5 -0
- package/dist/operations/geohash.js +17 -0
- package/dist/operations/gift-wrap.d.ts +13 -0
- package/dist/operations/gift-wrap.js +93 -0
- package/dist/operations/group.d.ts +11 -0
- package/dist/operations/group.js +34 -0
- package/dist/operations/hashtags.d.ts +7 -0
- package/dist/operations/hashtags.js +17 -0
- package/dist/operations/highlight.d.ts +18 -0
- package/dist/operations/highlight.js +47 -0
- package/dist/operations/index.d.ts +28 -0
- package/dist/operations/index.js +28 -0
- package/dist/operations/legacy-message.d.ts +6 -0
- package/dist/operations/legacy-message.js +13 -0
- package/dist/operations/list.d.ts +7 -0
- package/dist/operations/list.js +14 -0
- package/dist/operations/live-stream.d.ts +4 -0
- package/dist/operations/live-stream.js +11 -0
- package/dist/operations/media-attachment.d.ts +4 -0
- package/dist/operations/media-attachment.js +12 -0
- package/dist/operations/note.d.ts +9 -0
- package/dist/operations/note.js +42 -0
- package/dist/operations/picture-post.d.ts +4 -0
- package/dist/operations/picture-post.js +14 -0
- package/dist/operations/poll-response.d.ts +9 -0
- package/dist/operations/poll-response.js +20 -0
- package/dist/operations/poll.d.ts +19 -0
- package/dist/operations/poll.js +42 -0
- package/dist/operations/reaction.d.ts +7 -0
- package/dist/operations/reaction.js +39 -0
- package/dist/operations/share.d.ts +8 -0
- package/dist/operations/share.js +34 -0
- package/dist/operations/stream-chat.d.ts +7 -0
- package/dist/operations/stream-chat.js +27 -0
- package/dist/operations/stream.d.ts +41 -0
- package/dist/operations/stream.js +83 -0
- package/dist/operations/tag/bookmarks.d.ts +6 -0
- package/dist/operations/tag/bookmarks.js +20 -0
- package/dist/operations/tag/index.d.ts +1 -0
- package/dist/operations/tag/index.js +1 -0
- package/dist/operations/torrent.d.ts +33 -0
- package/dist/operations/torrent.js +66 -0
- package/dist/operations/wrapped-message.d.ts +12 -0
- package/dist/operations/wrapped-message.js +28 -0
- package/dist/operations/zap-split.d.ts +10 -0
- package/dist/operations/zap-split.js +20 -0
- package/dist/register.d.ts +11 -0
- package/dist/register.js +13 -0
- package/package.json +91 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { NostrEvent } from "applesauce-core/helpers/event";
|
|
2
|
+
export declare const ParsedReportSymbol: unique symbol;
|
|
3
|
+
export declare enum ReportReason {
|
|
4
|
+
nudity = "nudity",
|
|
5
|
+
malware = "malware",
|
|
6
|
+
profanity = "profanity",
|
|
7
|
+
illegal = "illegal",
|
|
8
|
+
spam = "spam",
|
|
9
|
+
impersonation = "impersonation",
|
|
10
|
+
other = "other"
|
|
11
|
+
}
|
|
12
|
+
export type ReportedUser = {
|
|
13
|
+
type: "user";
|
|
14
|
+
event: NostrEvent;
|
|
15
|
+
pubkey: string;
|
|
16
|
+
reason?: ReportReason;
|
|
17
|
+
};
|
|
18
|
+
export type ReportedEvent = {
|
|
19
|
+
type: "event";
|
|
20
|
+
event: NostrEvent;
|
|
21
|
+
comment?: string;
|
|
22
|
+
id: string;
|
|
23
|
+
pubkey: string;
|
|
24
|
+
reason?: ReportReason;
|
|
25
|
+
blobs?: string[];
|
|
26
|
+
};
|
|
27
|
+
/** Reads a report event as either a user or event report */
|
|
28
|
+
export declare function getReported(report: NostrEvent): ReportedEvent | ReportedUser;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { getOrComputeCachedValue } from "applesauce-core/helpers/cache";
|
|
2
|
+
import { isETag, isPTag } from "applesauce-core/helpers/tags";
|
|
3
|
+
export const ParsedReportSymbol = Symbol("parsed-report");
|
|
4
|
+
export var ReportReason;
|
|
5
|
+
(function (ReportReason) {
|
|
6
|
+
ReportReason["nudity"] = "nudity";
|
|
7
|
+
ReportReason["malware"] = "malware";
|
|
8
|
+
ReportReason["profanity"] = "profanity";
|
|
9
|
+
ReportReason["illegal"] = "illegal";
|
|
10
|
+
ReportReason["spam"] = "spam";
|
|
11
|
+
ReportReason["impersonation"] = "impersonation";
|
|
12
|
+
ReportReason["other"] = "other";
|
|
13
|
+
})(ReportReason || (ReportReason = {}));
|
|
14
|
+
/** Reads a report event as either a user or event report */
|
|
15
|
+
export function getReported(report) {
|
|
16
|
+
return getOrComputeCachedValue(report, ParsedReportSymbol, () => {
|
|
17
|
+
const p = report.tags.find(isPTag);
|
|
18
|
+
if (!p)
|
|
19
|
+
throw new Error("Report missing p tag");
|
|
20
|
+
const comment = report.content ? report.content.trim() : undefined;
|
|
21
|
+
const e = report.tags.find(isETag);
|
|
22
|
+
// Event report
|
|
23
|
+
if (e) {
|
|
24
|
+
const blobs = report.tags.filter((t) => t[0] === "x" && t[1]).map((t) => t[1]);
|
|
25
|
+
return {
|
|
26
|
+
type: "event",
|
|
27
|
+
event: report,
|
|
28
|
+
comment,
|
|
29
|
+
id: e[1],
|
|
30
|
+
pubkey: p[1],
|
|
31
|
+
reason: e[2],
|
|
32
|
+
blobs,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
// User report
|
|
36
|
+
return { type: "user", event: report, comment, pubkey: p[1], reason: p[2] };
|
|
37
|
+
});
|
|
38
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { KnownEvent } from "applesauce-core/helpers/event";
|
|
2
|
+
import { AddressPointer, EventPointer } from "applesauce-core/helpers/pointers";
|
|
3
|
+
import { kinds, NostrEvent } from "applesauce-core/helpers/event";
|
|
4
|
+
/** Type of a known share event */
|
|
5
|
+
export type ShareEvent = KnownEvent<kinds.Repost | kinds.GenericRepost>;
|
|
6
|
+
export declare const SharedEventSymbol: unique symbol;
|
|
7
|
+
export declare const SharedEventPointerSymbol: unique symbol;
|
|
8
|
+
export declare const SharedAddressPointerSymbol: unique symbol;
|
|
9
|
+
/** Returns the event pointer of a kind 6 or 16 share event */
|
|
10
|
+
export declare function getSharedEventPointer(event: ShareEvent): EventPointer;
|
|
11
|
+
export declare function getSharedEventPointer(event: NostrEvent): EventPointer | undefined;
|
|
12
|
+
/** Returns the address pointer of a kind 6 or 16 share event */
|
|
13
|
+
export declare function getSharedAddressPointer(event: NostrEvent): AddressPointer | undefined;
|
|
14
|
+
/** Returns the stringified event in the content of a kind 6 or 16 share event */
|
|
15
|
+
export declare function getEmbededSharedEvent(event: NostrEvent): NostrEvent | undefined;
|
|
16
|
+
/** @deprecated use getEmbededSharedEvent instead */
|
|
17
|
+
export declare const parseSharedEvent: typeof getEmbededSharedEvent;
|
|
18
|
+
/** Validates that an event is a valid share event */
|
|
19
|
+
export declare function isValidShare(event?: NostrEvent): event is ShareEvent;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { getOrComputeCachedValue, isEvent, safeParse, verifyWrappedEvent } from "applesauce-core/helpers";
|
|
2
|
+
import { getTagValue } from "applesauce-core/helpers/event";
|
|
3
|
+
import { getAddressPointerFromATag, getEventPointerFromETag, } from "applesauce-core/helpers/pointers";
|
|
4
|
+
import { isATag, isETag } from "applesauce-core/helpers/tags";
|
|
5
|
+
import { kinds } from "applesauce-core/helpers/event";
|
|
6
|
+
export const SharedEventSymbol = Symbol.for("shared-event");
|
|
7
|
+
export const SharedEventPointerSymbol = Symbol.for("shared-event-pointer");
|
|
8
|
+
export const SharedAddressPointerSymbol = Symbol.for("shared-address-pointer");
|
|
9
|
+
export function getSharedEventPointer(event) {
|
|
10
|
+
return getOrComputeCachedValue(event, SharedEventPointerSymbol, () => {
|
|
11
|
+
const e = event.tags.find(isETag);
|
|
12
|
+
if (!e)
|
|
13
|
+
return undefined;
|
|
14
|
+
// Get kind from k tag if it exists
|
|
15
|
+
const kStr = getTagValue(event, "k");
|
|
16
|
+
const k = kStr ? parseInt(kStr) : undefined;
|
|
17
|
+
const pointer = getEventPointerFromETag(e);
|
|
18
|
+
if (k !== undefined)
|
|
19
|
+
pointer.kind = k;
|
|
20
|
+
return pointer;
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/** Returns the address pointer of a kind 6 or 16 share event */
|
|
24
|
+
export function getSharedAddressPointer(event) {
|
|
25
|
+
return getOrComputeCachedValue(event, SharedAddressPointerSymbol, () => {
|
|
26
|
+
const a = event.tags.find(isATag);
|
|
27
|
+
if (!a)
|
|
28
|
+
return undefined;
|
|
29
|
+
return getAddressPointerFromATag(a);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/** Returns the stringified event in the content of a kind 6 or 16 share event */
|
|
33
|
+
export function getEmbededSharedEvent(event) {
|
|
34
|
+
return getOrComputeCachedValue(event, SharedEventSymbol, () => {
|
|
35
|
+
const pointer = getSharedEventPointer(event);
|
|
36
|
+
if (pointer === undefined || event.content === "")
|
|
37
|
+
return undefined;
|
|
38
|
+
const sharedEvent = safeParse(event.content);
|
|
39
|
+
// Ensure event is a valid Nostr event
|
|
40
|
+
if (!isEvent(sharedEvent))
|
|
41
|
+
return undefined;
|
|
42
|
+
// Ensure event id matches the pointer
|
|
43
|
+
if (sharedEvent.id !== pointer.id)
|
|
44
|
+
return undefined;
|
|
45
|
+
// Ensure event is verified
|
|
46
|
+
if (!verifyWrappedEvent(sharedEvent))
|
|
47
|
+
return undefined;
|
|
48
|
+
return sharedEvent;
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/** @deprecated use getEmbededSharedEvent instead */
|
|
52
|
+
export const parseSharedEvent = getEmbededSharedEvent;
|
|
53
|
+
/** Validates that an event is a valid share event */
|
|
54
|
+
export function isValidShare(event) {
|
|
55
|
+
if (!event)
|
|
56
|
+
return false;
|
|
57
|
+
return ((event.kind === kinds.Repost || event.kind === kinds.GenericRepost) && getSharedEventPointer(event) !== undefined);
|
|
58
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { NostrEvent } from "applesauce-core/helpers/event";
|
|
2
|
+
import { AddressPointer } from "applesauce-core/helpers/pointers";
|
|
3
|
+
/** Returns the pointer to the stream chat message stream */
|
|
4
|
+
export declare function getStreamChatMessageStream(message: NostrEvent): AddressPointer | undefined;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { getAddressPointerFromATag } from "applesauce-core/helpers/pointers";
|
|
2
|
+
import { isATag } from "applesauce-core/helpers/tags";
|
|
3
|
+
/** Returns the pointer to the stream chat message stream */
|
|
4
|
+
export function getStreamChatMessageStream(message) {
|
|
5
|
+
const tag = message.tags.find(isATag);
|
|
6
|
+
if (!tag)
|
|
7
|
+
return undefined;
|
|
8
|
+
return getAddressPointerFromATag(tag);
|
|
9
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { NostrEvent } from "applesauce-core/helpers/event";
|
|
2
|
+
import { EventPointer, ProfilePointer } from "applesauce-core/helpers/pointers";
|
|
3
|
+
export type StreamStatus = "live" | "ended" | "planned";
|
|
4
|
+
export type StreamRole = "host" | "participant" | "speaker";
|
|
5
|
+
export declare function getStreamTitle(stream: NostrEvent): string | undefined;
|
|
6
|
+
export declare function getStreamSummary(stream: NostrEvent): string | undefined;
|
|
7
|
+
export declare function getStreamImage(stream: NostrEvent): string | undefined;
|
|
8
|
+
/** Returns the status of the stream, defaults to ended if the stream is older than 2 weeks */
|
|
9
|
+
export declare function getStreamStatus(stream: NostrEvent): StreamStatus;
|
|
10
|
+
/** Returns the pubkey of the host of the stream */
|
|
11
|
+
export declare function getStreamHost(stream: NostrEvent): ProfilePointer;
|
|
12
|
+
/** Returns the participants of a stream */
|
|
13
|
+
export declare function getStreamParticipants(stream: NostrEvent): (ProfilePointer & {
|
|
14
|
+
role: StreamRole;
|
|
15
|
+
})[];
|
|
16
|
+
export declare function getStreamGoalPointer(stream: NostrEvent): EventPointer | undefined;
|
|
17
|
+
/** Gets all the streaming urls for a stream */
|
|
18
|
+
export declare function getStreamStreamingURLs(stream: NostrEvent): string[];
|
|
19
|
+
export declare function getStreamRecording(stream: NostrEvent): string | undefined;
|
|
20
|
+
/** Gets the relays for a stream */
|
|
21
|
+
export declare function getStreamRelays(stream: NostrEvent): string[] | undefined;
|
|
22
|
+
/** Gets the stream start time if it has one */
|
|
23
|
+
export declare function getStreamStartTime(stream: NostrEvent): number | undefined;
|
|
24
|
+
/** Gets the stream end time if it has one */
|
|
25
|
+
export declare function getStreamEndTime(stream: NostrEvent): number | undefined;
|
|
26
|
+
/** Returns the current number of participants in the stream */
|
|
27
|
+
export declare function getStreamViewers(stream: NostrEvent): number | undefined;
|
|
28
|
+
/** Returns the maximum number of participants in the stream */
|
|
29
|
+
export declare function getStreamMaxViewers(stream: NostrEvent): number | undefined;
|
|
30
|
+
/** Returns the hashtags for a stream */
|
|
31
|
+
export declare function getStreamHashtags(stream: NostrEvent): string[];
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { getTagValue } from "applesauce-core/helpers/event";
|
|
2
|
+
import { addRelayHintsToPointer, getEventPointerFromETag, getProfilePointerFromPTag, } from "applesauce-core/helpers/pointers";
|
|
3
|
+
import { mergeRelaySets } from "applesauce-core/helpers/relays";
|
|
4
|
+
import { isPTag } from "applesauce-core/helpers/tags";
|
|
5
|
+
import { unixNow } from "applesauce-core/helpers/time";
|
|
6
|
+
export function getStreamTitle(stream) {
|
|
7
|
+
return getTagValue(stream, "title");
|
|
8
|
+
}
|
|
9
|
+
export function getStreamSummary(stream) {
|
|
10
|
+
return getTagValue(stream, "summary");
|
|
11
|
+
}
|
|
12
|
+
export function getStreamImage(stream) {
|
|
13
|
+
return getTagValue(stream, "image");
|
|
14
|
+
}
|
|
15
|
+
const TWO_WEEKS = 60 * 60 * 24 * 14;
|
|
16
|
+
/** Returns the status of the stream, defaults to ended if the stream is older than 2 weeks */
|
|
17
|
+
export function getStreamStatus(stream) {
|
|
18
|
+
if (stream.created_at < unixNow() - TWO_WEEKS)
|
|
19
|
+
return "ended";
|
|
20
|
+
else
|
|
21
|
+
return getTagValue(stream, "status") || "ended";
|
|
22
|
+
}
|
|
23
|
+
/** Returns the pubkey of the host of the stream */
|
|
24
|
+
export function getStreamHost(stream) {
|
|
25
|
+
let host = undefined;
|
|
26
|
+
for (const tag of stream.tags) {
|
|
27
|
+
if (isPTag(tag) && (!host || (tag[3] && tag[3].toLowerCase() === "host"))) {
|
|
28
|
+
host = getProfilePointerFromPTag(tag);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return host || { pubkey: stream.pubkey };
|
|
32
|
+
}
|
|
33
|
+
/** Returns the participants of a stream */
|
|
34
|
+
export function getStreamParticipants(stream) {
|
|
35
|
+
return stream.tags
|
|
36
|
+
.filter((t) => isPTag(t) && t[3])
|
|
37
|
+
.map((t) => ({ ...getProfilePointerFromPTag(t), role: t[3].toLowerCase() }));
|
|
38
|
+
}
|
|
39
|
+
export function getStreamGoalPointer(stream) {
|
|
40
|
+
const goalTag = stream.tags.find((t) => t[0] === "goal");
|
|
41
|
+
return goalTag && addRelayHintsToPointer(getEventPointerFromETag(goalTag), getStreamRelays(stream));
|
|
42
|
+
}
|
|
43
|
+
/** Gets all the streaming urls for a stream */
|
|
44
|
+
export function getStreamStreamingURLs(stream) {
|
|
45
|
+
return stream.tags.filter((t) => t[0] === "streaming").map((t) => t[1]);
|
|
46
|
+
}
|
|
47
|
+
export function getStreamRecording(stream) {
|
|
48
|
+
return getTagValue(stream, "recording");
|
|
49
|
+
}
|
|
50
|
+
/** Gets the relays for a stream */
|
|
51
|
+
export function getStreamRelays(stream) {
|
|
52
|
+
for (const tag of stream.tags) {
|
|
53
|
+
if (tag[0] === "relays")
|
|
54
|
+
return mergeRelaySets(tag.slice(1));
|
|
55
|
+
}
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
/** Gets the stream start time if it has one */
|
|
59
|
+
export function getStreamStartTime(stream) {
|
|
60
|
+
const str = getTagValue(stream, "starts");
|
|
61
|
+
return str ? parseInt(str) : undefined;
|
|
62
|
+
}
|
|
63
|
+
/** Gets the stream end time if it has one */
|
|
64
|
+
export function getStreamEndTime(stream) {
|
|
65
|
+
const str = getTagValue(stream, "ends");
|
|
66
|
+
return str ? parseInt(str) : getStreamStatus(stream) === "ended" ? stream.created_at : undefined;
|
|
67
|
+
}
|
|
68
|
+
/** Returns the current number of participants in the stream */
|
|
69
|
+
export function getStreamViewers(stream) {
|
|
70
|
+
const viewers = getTagValue(stream, "current_participants");
|
|
71
|
+
return viewers ? parseInt(viewers) : undefined;
|
|
72
|
+
}
|
|
73
|
+
/** Returns the maximum number of participants in the stream */
|
|
74
|
+
export function getStreamMaxViewers(stream) {
|
|
75
|
+
const viewers = getTagValue(stream, "total_participants");
|
|
76
|
+
return viewers ? parseInt(viewers) : undefined;
|
|
77
|
+
}
|
|
78
|
+
/** Returns the hashtags for a stream */
|
|
79
|
+
export function getStreamHashtags(stream) {
|
|
80
|
+
return stream.tags.filter((t) => t[0] === "t").map((t) => t[1]);
|
|
81
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { EventTemplate, NostrEvent } from "applesauce-core/helpers/event";
|
|
2
|
+
import { AddressPointer, EventPointer } from "applesauce-core/helpers/pointers";
|
|
3
|
+
export type ThreadReferences = {
|
|
4
|
+
root?: {
|
|
5
|
+
e: EventPointer;
|
|
6
|
+
a: undefined;
|
|
7
|
+
} | {
|
|
8
|
+
e: undefined;
|
|
9
|
+
a: AddressPointer;
|
|
10
|
+
} | {
|
|
11
|
+
e: EventPointer;
|
|
12
|
+
a: AddressPointer;
|
|
13
|
+
};
|
|
14
|
+
reply?: {
|
|
15
|
+
e: EventPointer;
|
|
16
|
+
a: undefined;
|
|
17
|
+
} | {
|
|
18
|
+
e: undefined;
|
|
19
|
+
a: AddressPointer;
|
|
20
|
+
} | {
|
|
21
|
+
e: EventPointer;
|
|
22
|
+
a: AddressPointer;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
export declare const Nip10ThreadRefsSymbol: unique symbol;
|
|
26
|
+
/**
|
|
27
|
+
* Gets an EventPointer form a NIP-10 threading "e" tag
|
|
28
|
+
* @throws
|
|
29
|
+
*/
|
|
30
|
+
export declare function getEventPointerFromThreadTag(tag: string[]): EventPointer;
|
|
31
|
+
/** Parses NIP-10 tags and handles legacy behavior */
|
|
32
|
+
export declare function interpretThreadTags(tags: string[][]): {
|
|
33
|
+
root?: {
|
|
34
|
+
e: string[];
|
|
35
|
+
a: undefined;
|
|
36
|
+
} | {
|
|
37
|
+
e: undefined;
|
|
38
|
+
a: string[];
|
|
39
|
+
} | {
|
|
40
|
+
e: string[];
|
|
41
|
+
a: string[];
|
|
42
|
+
};
|
|
43
|
+
reply?: {
|
|
44
|
+
e: string[];
|
|
45
|
+
a: undefined;
|
|
46
|
+
} | {
|
|
47
|
+
e: undefined;
|
|
48
|
+
a: string[];
|
|
49
|
+
} | {
|
|
50
|
+
e: string[];
|
|
51
|
+
a: string[];
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
/** Returns the parsed NIP-10 tags for an event */
|
|
55
|
+
export declare function getNip10References(event: NostrEvent | EventTemplate): ThreadReferences;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { getOrComputeCachedValue } from "applesauce-core/helpers/cache";
|
|
2
|
+
import { getAddressPointerFromATag } from "applesauce-core/helpers/pointers";
|
|
3
|
+
import { isSafeRelayURL } from "applesauce-core/helpers/relays";
|
|
4
|
+
export const Nip10ThreadRefsSymbol = Symbol.for("nip10-thread-refs");
|
|
5
|
+
/**
|
|
6
|
+
* Gets an EventPointer form a NIP-10 threading "e" tag
|
|
7
|
+
* @throws
|
|
8
|
+
*/
|
|
9
|
+
export function getEventPointerFromThreadTag(tag) {
|
|
10
|
+
if (!tag[1])
|
|
11
|
+
throw new Error("Missing event id in tag");
|
|
12
|
+
let pointer = { id: tag[1] };
|
|
13
|
+
if (tag[2] && isSafeRelayURL(tag[2]))
|
|
14
|
+
pointer.relays = [tag[2]];
|
|
15
|
+
// get author from NIP-18 quote tags, nip-22 comments tags, or nip-10 thread tags
|
|
16
|
+
if (tag[0] === "e" &&
|
|
17
|
+
(tag[3] === "root" || tag[3] === "reply" || tag[3] === "mention") &&
|
|
18
|
+
tag[4] &&
|
|
19
|
+
tag[4].length === 64) {
|
|
20
|
+
// NIP-10 "e" tag
|
|
21
|
+
pointer.author = tag[4];
|
|
22
|
+
}
|
|
23
|
+
return pointer;
|
|
24
|
+
}
|
|
25
|
+
/** Parses NIP-10 tags and handles legacy behavior */
|
|
26
|
+
export function interpretThreadTags(tags) {
|
|
27
|
+
const eTags = tags.filter((t) => t[0] === "e" && t[1]);
|
|
28
|
+
const aTags = tags.filter((t) => t[0] === "a" && t[1]);
|
|
29
|
+
// find the root and reply tags.
|
|
30
|
+
let rootETag = eTags.find((t) => t[3] === "root");
|
|
31
|
+
let replyETag = eTags.find((t) => t[3] === "reply");
|
|
32
|
+
let rootATag = aTags.find((t) => t[3] === "root");
|
|
33
|
+
let replyATag = aTags.find((t) => t[3] === "reply");
|
|
34
|
+
if (!rootETag || !replyETag) {
|
|
35
|
+
// a direct reply does not need a "reply" reference
|
|
36
|
+
// https://github.com/nostr-protocol/nips/blob/master/10.md
|
|
37
|
+
// this is not necessarily to spec. but if there is only one id (root or reply) then assign it to both
|
|
38
|
+
// this handles the cases where a client only set a "reply" tag and no root
|
|
39
|
+
rootETag = replyETag = rootETag || replyETag;
|
|
40
|
+
}
|
|
41
|
+
if (!rootATag || !replyATag) {
|
|
42
|
+
rootATag = replyATag = rootATag || replyATag;
|
|
43
|
+
}
|
|
44
|
+
if (!rootETag && !replyETag) {
|
|
45
|
+
// legacy behavior
|
|
46
|
+
// https://github.com/nostr-protocol/nips/blob/master/10.md#positional-e-tags-deprecated
|
|
47
|
+
const legacyETags = eTags.filter((t) => {
|
|
48
|
+
// ignore it if there is a marker
|
|
49
|
+
if (t[3])
|
|
50
|
+
return false;
|
|
51
|
+
return true;
|
|
52
|
+
});
|
|
53
|
+
if (legacyETags.length >= 1) {
|
|
54
|
+
// first tag is the root
|
|
55
|
+
rootETag = legacyETags[0];
|
|
56
|
+
// last tag is reply
|
|
57
|
+
replyETag = legacyETags[legacyETags.length - 1] ?? rootETag;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
root: rootETag || rootATag ? { e: rootETag, a: rootATag } : undefined,
|
|
62
|
+
reply: replyETag || replyATag ? { e: replyETag, a: replyATag } : undefined,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/** Returns the parsed NIP-10 tags for an event */
|
|
66
|
+
export function getNip10References(event) {
|
|
67
|
+
return getOrComputeCachedValue(event, Nip10ThreadRefsSymbol, () => {
|
|
68
|
+
const tags = interpretThreadTags(event.tags);
|
|
69
|
+
let root;
|
|
70
|
+
if (tags.root) {
|
|
71
|
+
try {
|
|
72
|
+
root = {
|
|
73
|
+
e: tags.root.e && getEventPointerFromThreadTag(tags.root.e),
|
|
74
|
+
a: tags.root.a && getAddressPointerFromATag(tags.root.a),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
catch (error) { }
|
|
78
|
+
}
|
|
79
|
+
let reply;
|
|
80
|
+
if (tags.reply) {
|
|
81
|
+
try {
|
|
82
|
+
reply = {
|
|
83
|
+
e: tags.reply.e && getEventPointerFromThreadTag(tags.reply.e),
|
|
84
|
+
a: tags.reply.a && getAddressPointerFromATag(tags.reply.a),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
catch (error) { }
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
root,
|
|
91
|
+
reply,
|
|
92
|
+
};
|
|
93
|
+
});
|
|
94
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { KnownEvent, NostrEvent } from "applesauce-core/helpers/event";
|
|
2
|
+
export declare const TORRENT_KIND = 2003;
|
|
3
|
+
/** Type for validated torrent events */
|
|
4
|
+
export type TorrentEvent = KnownEvent<typeof TORRENT_KIND>;
|
|
5
|
+
/** A file entry inside a torrent */
|
|
6
|
+
export type TorrentFile = {
|
|
7
|
+
/** Full path of the file, e.g., "info/example.txt" */
|
|
8
|
+
name: string;
|
|
9
|
+
/** Size of the file in bytes (optional) */
|
|
10
|
+
size?: number;
|
|
11
|
+
};
|
|
12
|
+
/** Supported external identifier prefixes for torrents (excluding tcat and newznab, which are handled separately) */
|
|
13
|
+
export type TorrentExternalIdentifierPrefix = "tmdb" | "ttvdb" | "imdb" | "mal" | "anilist";
|
|
14
|
+
/** External identifier for a torrent */
|
|
15
|
+
export type TorrentExternalIdentifier = {
|
|
16
|
+
/** The prefix type */
|
|
17
|
+
prefix: TorrentExternalIdentifierPrefix;
|
|
18
|
+
/** The full identifier string (e.g., "tmdb:movie:693134") */
|
|
19
|
+
identifier: string;
|
|
20
|
+
/** For second-level prefixes, the media type (e.g., "movie", "anime", "manga") */
|
|
21
|
+
mediaType?: string;
|
|
22
|
+
/** The ID part of the identifier */
|
|
23
|
+
id: string;
|
|
24
|
+
};
|
|
25
|
+
/** Returns the BitTorrent info hash from the `x` tag */
|
|
26
|
+
export declare function getTorrentInfoHash(torrent: TorrentEvent): string;
|
|
27
|
+
export declare function getTorrentInfoHash(torrent: NostrEvent): string | undefined;
|
|
28
|
+
/** Returns the torrent title from the `title` tag */
|
|
29
|
+
export declare function getTorrentTitle(torrent: NostrEvent): string | undefined;
|
|
30
|
+
/** Returns all file entries from `file` tags */
|
|
31
|
+
export declare function getTorrentFiles(torrent: NostrEvent): TorrentFile[];
|
|
32
|
+
/** Returns all tracker URLs from `tracker` tags */
|
|
33
|
+
export declare function getTorrentTrackers(torrent: NostrEvent): string[];
|
|
34
|
+
/** Returns the newznab category ID from the `i` tag with `newznab:` prefix */
|
|
35
|
+
export declare function getTorrentCategory(torrent: NostrEvent): number | undefined;
|
|
36
|
+
/** Returns all search tags (for searchability) from `t` tags */
|
|
37
|
+
export declare function getTorrentSearchTags(torrent: NostrEvent): string[];
|
|
38
|
+
/** Returns the category path from the `tcat` identifier in `i` tags (e.g., "video,movie,4k") */
|
|
39
|
+
export declare function getTorrentCategoryPath(torrent: NostrEvent): string | undefined;
|
|
40
|
+
/** Returns all external identifiers from `i` tags (excluding tcat and newznab, which are handled separately) */
|
|
41
|
+
export declare function getTorrentExternalIdentifiers(torrent: NostrEvent): TorrentExternalIdentifier[];
|
|
42
|
+
/**
|
|
43
|
+
* Creates a TorrentExternalIdentifier object from prefix, id, and optional mediaType
|
|
44
|
+
* Automatically constructs the full identifier string
|
|
45
|
+
*/
|
|
46
|
+
export declare function createTorrentExternalIdentifier(prefix: TorrentExternalIdentifierPrefix, id: string, mediaType?: string): TorrentExternalIdentifier;
|
|
47
|
+
/**
|
|
48
|
+
* Builds a magnet link from an info hash, optional trackers, and optional name
|
|
49
|
+
* Format: magnet:?xt=urn:btih:${infoHash}${trackers ? '&tr=' + trackers.join('&tr=') : ''}${name ? '&dn=' + encodeURIComponent(name) : ''}
|
|
50
|
+
*/
|
|
51
|
+
export declare function buildTorrentMagnetLink(infoHash: string, trackers?: string[], name?: string): string;
|
|
52
|
+
/** Returns the magnet link for a torrent, building it from the event if needed */
|
|
53
|
+
export declare function getTorrentMagnetLink(torrent: NostrEvent): string | undefined;
|
|
54
|
+
/** Validates that an event is a valid torrent event (kind 2003 with required `x` tag) */
|
|
55
|
+
export declare function isValidTorrent(torrent: NostrEvent): torrent is TorrentEvent;
|