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,270 @@
|
|
|
1
|
+
import { getOrComputeCachedValue } from "applesauce-core/helpers/cache";
|
|
2
|
+
import { getTagValue } from "applesauce-core/helpers/event";
|
|
3
|
+
export const TORRENT_KIND = 2003;
|
|
4
|
+
const TorrentInfoHashSymbol = Symbol.for("torrent-info-hash");
|
|
5
|
+
const TorrentTitleSymbol = Symbol.for("torrent-title");
|
|
6
|
+
const TorrentFilesSymbol = Symbol.for("torrent-files");
|
|
7
|
+
const TorrentTrackersSymbol = Symbol.for("torrent-trackers");
|
|
8
|
+
const TorrentCategorySymbol = Symbol.for("torrent-category");
|
|
9
|
+
const TorrentSearchTagsSymbol = Symbol.for("torrent-search-tags");
|
|
10
|
+
const TorrentCategoryPathSymbol = Symbol.for("torrent-category-path");
|
|
11
|
+
const TorrentExternalIdentifiersSymbol = Symbol.for("torrent-external-identifiers");
|
|
12
|
+
const TorrentMagnetLinkSymbol = Symbol.for("torrent-magnet-link");
|
|
13
|
+
export function getTorrentInfoHash(torrent) {
|
|
14
|
+
if (torrent.kind !== TORRENT_KIND)
|
|
15
|
+
return undefined;
|
|
16
|
+
return getOrComputeCachedValue(torrent, TorrentInfoHashSymbol, () => {
|
|
17
|
+
return getTagValue(torrent, "x");
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
/** Returns the torrent title from the `title` tag */
|
|
21
|
+
export function getTorrentTitle(torrent) {
|
|
22
|
+
if (torrent.kind !== TORRENT_KIND)
|
|
23
|
+
return undefined;
|
|
24
|
+
return getOrComputeCachedValue(torrent, TorrentTitleSymbol, () => {
|
|
25
|
+
return getTagValue(torrent, "title");
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/** Returns all file entries from `file` tags */
|
|
29
|
+
export function getTorrentFiles(torrent) {
|
|
30
|
+
if (torrent.kind !== TORRENT_KIND)
|
|
31
|
+
return [];
|
|
32
|
+
return getOrComputeCachedValue(torrent, TorrentFilesSymbol, () => {
|
|
33
|
+
const files = [];
|
|
34
|
+
for (const tag of torrent.tags) {
|
|
35
|
+
if (tag[0] === "file" && tag[1]) {
|
|
36
|
+
const file = {
|
|
37
|
+
name: tag[1],
|
|
38
|
+
};
|
|
39
|
+
// Optional size in bytes (tag[2])
|
|
40
|
+
if (tag[2]) {
|
|
41
|
+
const size = parseInt(tag[2], 10);
|
|
42
|
+
if (!Number.isNaN(size)) {
|
|
43
|
+
file.size = size;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
files.push(file);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return files;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
/** Returns all tracker URLs from `tracker` tags */
|
|
53
|
+
export function getTorrentTrackers(torrent) {
|
|
54
|
+
if (torrent.kind !== TORRENT_KIND)
|
|
55
|
+
return [];
|
|
56
|
+
return getOrComputeCachedValue(torrent, TorrentTrackersSymbol, () => {
|
|
57
|
+
const trackers = [];
|
|
58
|
+
for (const tag of torrent.tags) {
|
|
59
|
+
if (tag[0] === "tracker" && tag[1])
|
|
60
|
+
trackers.push(tag[1]);
|
|
61
|
+
}
|
|
62
|
+
return trackers;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/** Returns the newznab category ID from the `i` tag with `newznab:` prefix */
|
|
66
|
+
export function getTorrentCategory(torrent) {
|
|
67
|
+
if (torrent.kind !== TORRENT_KIND)
|
|
68
|
+
return undefined;
|
|
69
|
+
return getOrComputeCachedValue(torrent, TorrentCategorySymbol, () => {
|
|
70
|
+
for (const tag of torrent.tags) {
|
|
71
|
+
if (tag[0] === "i" && tag[1]?.startsWith("newznab:")) {
|
|
72
|
+
const categoryId = parseInt(tag[1].slice(8), 10); // Return the ID after "newznab:"
|
|
73
|
+
if (!Number.isNaN(categoryId)) {
|
|
74
|
+
return categoryId;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return undefined;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/** Returns all search tags (for searchability) from `t` tags */
|
|
82
|
+
export function getTorrentSearchTags(torrent) {
|
|
83
|
+
if (torrent.kind !== TORRENT_KIND)
|
|
84
|
+
return [];
|
|
85
|
+
return getOrComputeCachedValue(torrent, TorrentSearchTagsSymbol, () => {
|
|
86
|
+
const tags = [];
|
|
87
|
+
for (const tag of torrent.tags) {
|
|
88
|
+
if (tag[0] === "t" && tag[1])
|
|
89
|
+
tags.push(tag[1]);
|
|
90
|
+
}
|
|
91
|
+
return tags;
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/** Returns the category path from the `tcat` identifier in `i` tags (e.g., "video,movie,4k") */
|
|
95
|
+
export function getTorrentCategoryPath(torrent) {
|
|
96
|
+
if (torrent.kind !== TORRENT_KIND)
|
|
97
|
+
return undefined;
|
|
98
|
+
return getOrComputeCachedValue(torrent, TorrentCategoryPathSymbol, () => {
|
|
99
|
+
for (const tag of torrent.tags) {
|
|
100
|
+
if (tag[0] === "i" && tag[1]?.startsWith("tcat:")) {
|
|
101
|
+
return tag[1].slice(5); // Return the path after "tcat:"
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return undefined;
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Parses an external identifier from an `i` tag value
|
|
109
|
+
* Supports prefixes: tmdb, ttvdb, imdb, mal, anilist
|
|
110
|
+
* Supports second-level prefixes: tmdb:movie, ttvdb:movie, mal:anime, mal:manga
|
|
111
|
+
* Note: tcat is excluded as it's handled separately via getTorrentCategoryPath
|
|
112
|
+
* Note: newznab is excluded as it's handled separately via getTorrentCategory
|
|
113
|
+
*/
|
|
114
|
+
function parseTorrentExternalIdentifier(value) {
|
|
115
|
+
// Skip tcat - it's handled separately as a category path
|
|
116
|
+
if (value.startsWith("tcat:"))
|
|
117
|
+
return null;
|
|
118
|
+
// Skip newznab - it's handled separately as categories
|
|
119
|
+
if (value.startsWith("newznab:"))
|
|
120
|
+
return null;
|
|
121
|
+
// tmdb:movie:693134 or tmdb:693134
|
|
122
|
+
if (value.startsWith("tmdb:")) {
|
|
123
|
+
const rest = value.slice(5);
|
|
124
|
+
const parts = rest.split(":");
|
|
125
|
+
if (parts.length === 2) {
|
|
126
|
+
return {
|
|
127
|
+
prefix: "tmdb",
|
|
128
|
+
identifier: value,
|
|
129
|
+
mediaType: parts[0],
|
|
130
|
+
id: parts[1],
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
return {
|
|
135
|
+
prefix: "tmdb",
|
|
136
|
+
identifier: value,
|
|
137
|
+
id: rest,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// ttvdb:movie:290272 or ttvdb:290272
|
|
142
|
+
if (value.startsWith("ttvdb:")) {
|
|
143
|
+
const rest = value.slice(6);
|
|
144
|
+
const parts = rest.split(":");
|
|
145
|
+
if (parts.length === 2) {
|
|
146
|
+
return {
|
|
147
|
+
prefix: "ttvdb",
|
|
148
|
+
identifier: value,
|
|
149
|
+
mediaType: parts[0],
|
|
150
|
+
id: parts[1],
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
return {
|
|
155
|
+
prefix: "ttvdb",
|
|
156
|
+
identifier: value,
|
|
157
|
+
id: rest,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// imdb:tt15239678
|
|
162
|
+
if (value.startsWith("imdb:")) {
|
|
163
|
+
return {
|
|
164
|
+
prefix: "imdb",
|
|
165
|
+
identifier: value,
|
|
166
|
+
id: value.slice(5),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
// mal:anime:9253 or mal:manga:17517 or mal:9253
|
|
170
|
+
if (value.startsWith("mal:")) {
|
|
171
|
+
const rest = value.slice(4);
|
|
172
|
+
const parts = rest.split(":");
|
|
173
|
+
if (parts.length === 2) {
|
|
174
|
+
return {
|
|
175
|
+
prefix: "mal",
|
|
176
|
+
identifier: value,
|
|
177
|
+
mediaType: parts[0],
|
|
178
|
+
id: parts[1],
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
return {
|
|
183
|
+
prefix: "mal",
|
|
184
|
+
identifier: value,
|
|
185
|
+
id: rest,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// anilist:12345
|
|
190
|
+
if (value.startsWith("anilist:")) {
|
|
191
|
+
return {
|
|
192
|
+
prefix: "anilist",
|
|
193
|
+
identifier: value,
|
|
194
|
+
id: value.slice(8),
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
/** Returns all external identifiers from `i` tags (excluding tcat and newznab, which are handled separately) */
|
|
200
|
+
export function getTorrentExternalIdentifiers(torrent) {
|
|
201
|
+
if (torrent.kind !== TORRENT_KIND)
|
|
202
|
+
return [];
|
|
203
|
+
return getOrComputeCachedValue(torrent, TorrentExternalIdentifiersSymbol, () => {
|
|
204
|
+
const identifiers = [];
|
|
205
|
+
for (const tag of torrent.tags) {
|
|
206
|
+
if (tag[0] === "i" && tag[1]) {
|
|
207
|
+
const parsed = parseTorrentExternalIdentifier(tag[1]);
|
|
208
|
+
if (parsed) {
|
|
209
|
+
identifiers.push(parsed);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return identifiers;
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Creates a TorrentExternalIdentifier object from prefix, id, and optional mediaType
|
|
218
|
+
* Automatically constructs the full identifier string
|
|
219
|
+
*/
|
|
220
|
+
export function createTorrentExternalIdentifier(prefix, id, mediaType) {
|
|
221
|
+
let identifier;
|
|
222
|
+
// Build identifier string based on prefix and whether mediaType is provided
|
|
223
|
+
if (mediaType) {
|
|
224
|
+
// For prefixes that support mediaType: tmdb, ttvdb, mal
|
|
225
|
+
identifier = `${prefix}:${mediaType}:${id}`;
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
// Simple format: prefix:id
|
|
229
|
+
identifier = `${prefix}:${id}`;
|
|
230
|
+
}
|
|
231
|
+
return {
|
|
232
|
+
prefix,
|
|
233
|
+
identifier,
|
|
234
|
+
mediaType,
|
|
235
|
+
id,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Builds a magnet link from an info hash, optional trackers, and optional name
|
|
240
|
+
* Format: magnet:?xt=urn:btih:${infoHash}${trackers ? '&tr=' + trackers.join('&tr=') : ''}${name ? '&dn=' + encodeURIComponent(name) : ''}
|
|
241
|
+
*/
|
|
242
|
+
export function buildTorrentMagnetLink(infoHash, trackers, name) {
|
|
243
|
+
const parts = [`magnet:?xt=urn:btih:${infoHash}`];
|
|
244
|
+
if (trackers && trackers.length > 0) {
|
|
245
|
+
for (const tracker of trackers) {
|
|
246
|
+
parts.push(`&tr=${encodeURIComponent(tracker)}`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
if (name) {
|
|
250
|
+
parts.push(`&dn=${encodeURIComponent(name)}`);
|
|
251
|
+
}
|
|
252
|
+
return parts.join("");
|
|
253
|
+
}
|
|
254
|
+
/** Returns the magnet link for a torrent, building it from the event if needed */
|
|
255
|
+
export function getTorrentMagnetLink(torrent) {
|
|
256
|
+
if (torrent.kind !== TORRENT_KIND)
|
|
257
|
+
return undefined;
|
|
258
|
+
return getOrComputeCachedValue(torrent, TorrentMagnetLinkSymbol, () => {
|
|
259
|
+
const infoHash = getTorrentInfoHash(torrent);
|
|
260
|
+
if (!infoHash)
|
|
261
|
+
return undefined;
|
|
262
|
+
const trackers = getTorrentTrackers(torrent);
|
|
263
|
+
const title = getTorrentTitle(torrent);
|
|
264
|
+
return buildTorrentMagnetLink(infoHash, trackers.length > 0 ? trackers : undefined, title);
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
/** Validates that an event is a valid torrent event (kind 2003 with required `x` tag) */
|
|
268
|
+
export function isValidTorrent(torrent) {
|
|
269
|
+
return torrent.kind === TORRENT_KIND && getTorrentInfoHash(torrent) !== undefined;
|
|
270
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { NostrEvent } from "applesauce-core/helpers/event";
|
|
2
|
+
import { AddressPointer, EventPointer, ProfilePointer } from "applesauce-core/helpers/pointers";
|
|
3
|
+
export declare const UserStatusPointerSymbol: unique symbol;
|
|
4
|
+
export type UserStatusPointer = {
|
|
5
|
+
type: "nevent";
|
|
6
|
+
data: EventPointer;
|
|
7
|
+
} | {
|
|
8
|
+
type: "nprofile";
|
|
9
|
+
data: ProfilePointer;
|
|
10
|
+
} | {
|
|
11
|
+
type: "naddr";
|
|
12
|
+
data: AddressPointer;
|
|
13
|
+
} | {
|
|
14
|
+
type: "url";
|
|
15
|
+
data: string;
|
|
16
|
+
};
|
|
17
|
+
/** Gets the {@link UserStatusPointer} for a status event */
|
|
18
|
+
export declare function getUserStatusPointer(status: NostrEvent): UserStatusPointer | null;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { getOrComputeCachedValue } from "applesauce-core/helpers/cache";
|
|
2
|
+
import { getAddressPointerFromATag, getEventPointerFromETag, getProfilePointerFromPTag, } from "applesauce-core/helpers/pointers";
|
|
3
|
+
export const UserStatusPointerSymbol = Symbol.for("user-status-pointer");
|
|
4
|
+
function getStatusPointer(status) {
|
|
5
|
+
const pTag = status.tags.find((t) => t[0] === "p" && t[1]);
|
|
6
|
+
if (pTag)
|
|
7
|
+
return { type: "nprofile", data: getProfilePointerFromPTag(pTag) };
|
|
8
|
+
const eTag = status.tags.find((t) => t[0] === "e" && t[1]);
|
|
9
|
+
if (eTag)
|
|
10
|
+
return { type: "nevent", data: getEventPointerFromETag(eTag) };
|
|
11
|
+
const aTag = status.tags.find((t) => t[0] === "a" && t[1]);
|
|
12
|
+
if (aTag)
|
|
13
|
+
return { type: "naddr", data: getAddressPointerFromATag(aTag) };
|
|
14
|
+
const rTag = status.tags.find((t) => t[0] === "r" && t[1]);
|
|
15
|
+
if (rTag)
|
|
16
|
+
return { type: "url", data: rTag[1] };
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
/** Gets the {@link UserStatusPointer} for a status event */
|
|
20
|
+
export function getUserStatusPointer(status) {
|
|
21
|
+
return getOrComputeCachedValue(status, UserStatusPointerSymbol, () => getStatusPointer(status));
|
|
22
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Rumor } from "./gift-wrap.js";
|
|
2
|
+
/** Returns the subject of a wrapped direct message */
|
|
3
|
+
export declare function getWrappedMessageSubject(message: Rumor): string | undefined;
|
|
4
|
+
/** Returns the parent id of a wrapped direct message */
|
|
5
|
+
export declare function getWrappedMessageParent(message: Rumor): string | undefined;
|
|
6
|
+
/** Returns the sender of a wrapped direct message */
|
|
7
|
+
export declare function getWrappedMessageSender(message: Rumor): string;
|
|
8
|
+
/** @deprecated use {@link getWrappedMessageSender} instead */
|
|
9
|
+
export declare const getWrappedMesssageSender: typeof getWrappedMessageSender;
|
|
10
|
+
/**
|
|
11
|
+
* Returns the first participant in a conversation that is not the sender
|
|
12
|
+
* @see getConversationParticipants
|
|
13
|
+
*/
|
|
14
|
+
export declare function getWrappedMessageReceiver(message: Rumor): string;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { getTagValue } from "applesauce-core/helpers/event";
|
|
2
|
+
import { getConversationParticipants } from "./messages.js";
|
|
3
|
+
/** Returns the subject of a wrapped direct message */
|
|
4
|
+
export function getWrappedMessageSubject(message) {
|
|
5
|
+
return getTagValue(message, "subject");
|
|
6
|
+
}
|
|
7
|
+
/** Returns the parent id of a wrapped direct message */
|
|
8
|
+
export function getWrappedMessageParent(message) {
|
|
9
|
+
return getTagValue(message, "e");
|
|
10
|
+
}
|
|
11
|
+
/** Returns the sender of a wrapped direct message */
|
|
12
|
+
export function getWrappedMessageSender(message) {
|
|
13
|
+
return message.pubkey;
|
|
14
|
+
}
|
|
15
|
+
/** @deprecated use {@link getWrappedMessageSender} instead */
|
|
16
|
+
export const getWrappedMesssageSender = getWrappedMessageSender;
|
|
17
|
+
/**
|
|
18
|
+
* Returns the first participant in a conversation that is not the sender
|
|
19
|
+
* @see getConversationParticipants
|
|
20
|
+
*/
|
|
21
|
+
export function getWrappedMessageReceiver(message) {
|
|
22
|
+
return getConversationParticipants(message).filter((p) => p !== message.pubkey)[0];
|
|
23
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { KnownEvent } from "applesauce-core/helpers/event";
|
|
2
|
+
import { kinds, NostrEvent } from "applesauce-core/helpers/event";
|
|
3
|
+
import { AddressPointer, EventPointer } from "applesauce-core/helpers/pointers";
|
|
4
|
+
import { ParsedInvoice } from "./bolt11.js";
|
|
5
|
+
/** Type for validated zap event */
|
|
6
|
+
export type ZapEvent = KnownEvent<kinds.Zap>;
|
|
7
|
+
export declare const ZapRequestSymbol: unique symbol;
|
|
8
|
+
export declare const ZapSenderSymbol: unique symbol;
|
|
9
|
+
export declare const ZapReceiverSymbol: unique symbol;
|
|
10
|
+
export declare const ZapInvoiceSymbol: unique symbol;
|
|
11
|
+
export declare const ZapEventPointerSymbol: unique symbol;
|
|
12
|
+
export declare const ZapAddressPointerSymbol: unique symbol;
|
|
13
|
+
/** Returns the senders pubkey */
|
|
14
|
+
export declare function getZapSender(zap: ZapEvent): string;
|
|
15
|
+
export declare function getZapSender(zap: NostrEvent): string | undefined;
|
|
16
|
+
/** Gets the receivers pubkey */
|
|
17
|
+
export declare function getZapRecipient(zap: ZapEvent): string;
|
|
18
|
+
export declare function getZapRecipient(zap: NostrEvent): string | undefined;
|
|
19
|
+
/** Returns the parsed bolt11 invoice */
|
|
20
|
+
export declare function getZapPayment(zap: ZapEvent): ParsedInvoice;
|
|
21
|
+
export declare function getZapPayment(zap: NostrEvent): ParsedInvoice | undefined;
|
|
22
|
+
/** Returns the zap event amount in msats */
|
|
23
|
+
export declare function getZapAmount(zap: ZapEvent): number;
|
|
24
|
+
export declare function getZapAmount(zap: NostrEvent): number | undefined;
|
|
25
|
+
/** Gets the AddressPointer that was zapped */
|
|
26
|
+
export declare function getZapAddressPointer(zap: NostrEvent): AddressPointer | null;
|
|
27
|
+
/** Gets the EventPointer that was zapped */
|
|
28
|
+
export declare function getZapEventPointer(zap: NostrEvent): EventPointer | null;
|
|
29
|
+
/** Gets the preimage for the bolt11 invoice */
|
|
30
|
+
export declare function getZapPreimage(zap: NostrEvent): string | undefined;
|
|
31
|
+
/** Returns the zap request event inside the zap receipt */
|
|
32
|
+
export declare function getZapRequest(zap: ZapEvent): NostrEvent;
|
|
33
|
+
export declare function getZapRequest(zap: NostrEvent): NostrEvent | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Checks if a zap event is valid (not missing fields)
|
|
36
|
+
* DOES NOT validate LNURL address
|
|
37
|
+
*/
|
|
38
|
+
export declare function isValidZap(zap?: NostrEvent): zap is ZapEvent;
|
|
39
|
+
export type ZapSplit = {
|
|
40
|
+
pubkey: string;
|
|
41
|
+
percent: number;
|
|
42
|
+
weight: number;
|
|
43
|
+
relay?: string;
|
|
44
|
+
};
|
|
45
|
+
/** Returns the zap splits for an event */
|
|
46
|
+
export declare function getZapSplits(event: NostrEvent): ZapSplit[] | undefined;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { getOrComputeCachedValue } from "applesauce-core/helpers/cache";
|
|
2
|
+
import { isEvent, verifyWrappedEvent } from "applesauce-core/helpers/event";
|
|
3
|
+
import { getTagValue } from "applesauce-core/helpers/event";
|
|
4
|
+
import { getAddressPointerFromATag, getEventPointerFromETag } from "applesauce-core/helpers/pointers";
|
|
5
|
+
import { isATag, isETag } from "applesauce-core/helpers/tags";
|
|
6
|
+
import { kinds } from "applesauce-core/helpers/event";
|
|
7
|
+
import { parseBolt11 } from "./bolt11.js";
|
|
8
|
+
export const ZapRequestSymbol = Symbol.for("zap-request");
|
|
9
|
+
export const ZapSenderSymbol = Symbol.for("zap-sender");
|
|
10
|
+
export const ZapReceiverSymbol = Symbol.for("zap-receiver");
|
|
11
|
+
export const ZapInvoiceSymbol = Symbol.for("zap-bolt11");
|
|
12
|
+
export const ZapEventPointerSymbol = Symbol.for("zap-event-pointer");
|
|
13
|
+
export const ZapAddressPointerSymbol = Symbol.for("zap-address-pointer");
|
|
14
|
+
export function getZapSender(zap) {
|
|
15
|
+
return getOrComputeCachedValue(zap, ZapSenderSymbol, () => {
|
|
16
|
+
return getTagValue(zap, "P") || getZapRequest(zap)?.pubkey;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
export function getZapRecipient(zap) {
|
|
20
|
+
return getOrComputeCachedValue(zap, ZapReceiverSymbol, () => {
|
|
21
|
+
return getTagValue(zap, "p");
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
export function getZapPayment(zap) {
|
|
25
|
+
return getOrComputeCachedValue(zap, ZapInvoiceSymbol, () => {
|
|
26
|
+
const bolt11 = getTagValue(zap, "bolt11");
|
|
27
|
+
try {
|
|
28
|
+
// Catch errors with parsing the bolt11 invoice
|
|
29
|
+
return bolt11 ? parseBolt11(bolt11) : undefined;
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
export function getZapAmount(zap) {
|
|
37
|
+
return getZapPayment(zap)?.amount;
|
|
38
|
+
}
|
|
39
|
+
/** Gets the AddressPointer that was zapped */
|
|
40
|
+
export function getZapAddressPointer(zap) {
|
|
41
|
+
return getOrComputeCachedValue(zap, ZapAddressPointerSymbol, () => {
|
|
42
|
+
const a = zap.tags.find(isATag);
|
|
43
|
+
return a ? getAddressPointerFromATag(a) : null;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/** Gets the EventPointer that was zapped */
|
|
47
|
+
export function getZapEventPointer(zap) {
|
|
48
|
+
return getOrComputeCachedValue(zap, ZapEventPointerSymbol, () => {
|
|
49
|
+
const e = zap.tags.find(isETag);
|
|
50
|
+
return e ? getEventPointerFromETag(e) : null;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
/** Gets the preimage for the bolt11 invoice */
|
|
54
|
+
export function getZapPreimage(zap) {
|
|
55
|
+
return getTagValue(zap, "preimage");
|
|
56
|
+
}
|
|
57
|
+
export function getZapRequest(zap) {
|
|
58
|
+
return getOrComputeCachedValue(zap, ZapRequestSymbol, () => {
|
|
59
|
+
const description = getTagValue(zap, "description");
|
|
60
|
+
if (!description)
|
|
61
|
+
return;
|
|
62
|
+
// Attempt to parse the zap request
|
|
63
|
+
try {
|
|
64
|
+
// Copied from nostr-tools/nip57 and modified to use the internal verifyZap method and return the zap request event
|
|
65
|
+
let zapRequest;
|
|
66
|
+
try {
|
|
67
|
+
zapRequest = JSON.parse(description);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
throw new Error("Invalid zap request JSON.");
|
|
71
|
+
}
|
|
72
|
+
if (!isEvent(zapRequest))
|
|
73
|
+
throw new Error("Zap request is not a valid Nostr event.");
|
|
74
|
+
if (!verifyWrappedEvent(zapRequest))
|
|
75
|
+
throw new Error("Invalid signature on zap request.");
|
|
76
|
+
let p = zapRequest.tags.find(([t, v]) => t === "p" && v);
|
|
77
|
+
if (!p)
|
|
78
|
+
throw new Error("Zap request doesn't have a 'p' tag.");
|
|
79
|
+
if (!p[1].match(/^[a-f0-9]{64}$/))
|
|
80
|
+
throw new Error("Zap request 'p' tag is not valid hex.");
|
|
81
|
+
let e = zapRequest.tags.find(([t, v]) => t === "e" && v);
|
|
82
|
+
if (e && !e[1].match(/^[a-f0-9]{64}$/))
|
|
83
|
+
throw new Error("Zap request 'e' tag is not valid hex.");
|
|
84
|
+
let relays = zapRequest.tags.find(([t, v]) => t === "relays" && v);
|
|
85
|
+
if (!relays)
|
|
86
|
+
throw new Error("Zap request doesn't have a 'relays' tag.");
|
|
87
|
+
return zapRequest;
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Checks if a zap event is valid (not missing fields)
|
|
96
|
+
* DOES NOT validate LNURL address
|
|
97
|
+
*/
|
|
98
|
+
export function isValidZap(zap) {
|
|
99
|
+
if (!zap)
|
|
100
|
+
return false;
|
|
101
|
+
if (zap.kind !== kinds.Zap)
|
|
102
|
+
return false;
|
|
103
|
+
// Is not a valid zap kind if any of these is undefined
|
|
104
|
+
if (getZapPayment(zap) === undefined)
|
|
105
|
+
return false;
|
|
106
|
+
if (getZapRequest(zap) === undefined)
|
|
107
|
+
return false;
|
|
108
|
+
if (getZapRecipient(zap) === undefined)
|
|
109
|
+
return false;
|
|
110
|
+
if (getZapSender(zap) === undefined)
|
|
111
|
+
return false;
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
/** Returns the zap splits for an event */
|
|
115
|
+
export function getZapSplits(event) {
|
|
116
|
+
const tags = event.tags.filter((t) => t[0] === "zap" && t[1] && t[3]);
|
|
117
|
+
if (tags.length > 0) {
|
|
118
|
+
const targets = tags
|
|
119
|
+
.map((t) => ({ pubkey: t[1], relay: t[2], weight: parseFloat(t[3]) }))
|
|
120
|
+
.filter((p) => Number.isFinite(p.weight));
|
|
121
|
+
const total = targets.reduce((v, p) => v + p.weight, 0);
|
|
122
|
+
return targets.map((p) => ({ ...p, percent: p.weight / total }));
|
|
123
|
+
}
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * as Helpers from "./helpers/index.js";
|
|
2
|
+
export * as Models from "./models/index.js";
|
|
3
|
+
export * as Operations from "./operations/index.js";
|
|
4
|
+
export * as Blueprints from "./blueprints/index.js";
|
|
5
|
+
// Register the common models and blueprints with the event store and event factory
|
|
6
|
+
import "./register.js";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Model } from "applesauce-core/event-store";
|
|
2
|
+
import { ProfilePointer } from "applesauce-core/helpers/pointers";
|
|
3
|
+
import { type Observable } from "rxjs";
|
|
4
|
+
/** A model that returns a users blossom servers */
|
|
5
|
+
export declare function UserBlossomServersModel(user: string | ProfilePointer): Model<URL[]>;
|
|
6
|
+
declare module "applesauce-core/event-store" {
|
|
7
|
+
interface EventModels {
|
|
8
|
+
/** Subscribe to a users blossom servers */
|
|
9
|
+
blossomServers(user: string | ProfilePointer): Observable<URL[]>;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { map } from "rxjs/operators";
|
|
2
|
+
import { BLOSSOM_SERVER_LIST_KIND, getBlossomServersFromList } from "../helpers/blossom.js";
|
|
3
|
+
// Import EventModels as a value (class) to modify its prototype
|
|
4
|
+
import { EventModels } from "applesauce-core/event-store";
|
|
5
|
+
/** A model that returns a users blossom servers */
|
|
6
|
+
export function UserBlossomServersModel(user) {
|
|
7
|
+
if (typeof user === "string")
|
|
8
|
+
user = { pubkey: user };
|
|
9
|
+
return (store) => store
|
|
10
|
+
.replaceable({ kind: BLOSSOM_SERVER_LIST_KIND, pubkey: user.pubkey, relays: user.relays })
|
|
11
|
+
.pipe(map((event) => (event ? getBlossomServersFromList(event) : [])));
|
|
12
|
+
}
|
|
13
|
+
// Register this model with EventModels
|
|
14
|
+
EventModels.prototype.blossomServers = function (user) {
|
|
15
|
+
if (typeof user === "string")
|
|
16
|
+
user = { pubkey: user };
|
|
17
|
+
return this.model(UserBlossomServersModel, user);
|
|
18
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Model } from "applesauce-core/event-store";
|
|
2
|
+
import { Bookmarks } from "../helpers/bookmark.js";
|
|
3
|
+
/** A model that returns all the bookmarks of a user */
|
|
4
|
+
export declare function UserBookmarkModel(pubkey: string): Model<Bookmarks | undefined>;
|
|
5
|
+
/** A model that returns all the public bookmarks of a user */
|
|
6
|
+
export declare function UserPublicBookmarkModel(pubkey: string): Model<Bookmarks | undefined>;
|
|
7
|
+
/** A model that returns all the hidden bookmarks of a user */
|
|
8
|
+
export declare function UserHiddenBookmarkModel(pubkey: string): Model<Bookmarks | null | undefined>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { kinds } from "applesauce-core/helpers/event";
|
|
2
|
+
import { watchEventUpdates } from "applesauce-core/observable";
|
|
3
|
+
import { map } from "rxjs/operators";
|
|
4
|
+
import { getBookmarks, getHiddenBookmarks, getPublicBookmarks } from "../helpers/bookmark.js";
|
|
5
|
+
/** A model that returns all the bookmarks of a user */
|
|
6
|
+
export function UserBookmarkModel(pubkey) {
|
|
7
|
+
return (events) => events.replaceable(kinds.Mutelist, pubkey).pipe(
|
|
8
|
+
// listen for event updates (hidden tags unlocked)
|
|
9
|
+
watchEventUpdates(events),
|
|
10
|
+
// Get all bookmarks
|
|
11
|
+
map((event) => event && getBookmarks(event)));
|
|
12
|
+
}
|
|
13
|
+
/** A model that returns all the public bookmarks of a user */
|
|
14
|
+
export function UserPublicBookmarkModel(pubkey) {
|
|
15
|
+
return (events) => events.replaceable(kinds.Mutelist, pubkey).pipe(map((event) => event && getPublicBookmarks(event)));
|
|
16
|
+
}
|
|
17
|
+
/** A model that returns all the hidden bookmarks of a user */
|
|
18
|
+
export function UserHiddenBookmarkModel(pubkey) {
|
|
19
|
+
return (events) => events.replaceable(kinds.Mutelist, pubkey).pipe(
|
|
20
|
+
// listen for event updates (hidden tags unlocked)
|
|
21
|
+
watchEventUpdates(events),
|
|
22
|
+
// Get hidden bookmarks
|
|
23
|
+
map((event) => event && (getHiddenBookmarks(event) ?? null)));
|
|
24
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Model } from "applesauce-core/event-store";
|
|
2
|
+
import { NostrEvent } from "applesauce-core/helpers/event";
|
|
3
|
+
/** A model that gets all the events for a calendar */
|
|
4
|
+
export declare function CalendarEventsModel(calendar: NostrEvent): Model<NostrEvent[]>;
|
|
5
|
+
/** A model that gets all the RSVPs for a calendar event */
|
|
6
|
+
export declare function CalendarEventRSVPsModel(event: NostrEvent): Model<NostrEvent[]>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { getReplaceableAddress } from "applesauce-core/helpers/event";
|
|
2
|
+
import { defined } from "applesauce-core/observable";
|
|
3
|
+
import { combineLatest } from "rxjs";
|
|
4
|
+
import { CALENDAR_EVENT_RSVP_KIND } from "../helpers/calendar-rsvp.js";
|
|
5
|
+
import { getCalendarAddressPointers } from "../helpers/calendar.js";
|
|
6
|
+
/** A model that gets all the events for a calendar */
|
|
7
|
+
export function CalendarEventsModel(calendar) {
|
|
8
|
+
return (events) => combineLatest(getCalendarAddressPointers(calendar).map((p) => events.replaceable(p.kind, p.pubkey, p.identifier).pipe(defined())));
|
|
9
|
+
}
|
|
10
|
+
/** A model that gets all the RSVPs for a calendar event */
|
|
11
|
+
export function CalendarEventRSVPsModel(event) {
|
|
12
|
+
return (events) => {
|
|
13
|
+
return events.timeline({ kinds: [CALENDAR_EVENT_RSVP_KIND], "#a": [getReplaceableAddress(event)] });
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Model } from "applesauce-core/event-store";
|
|
2
|
+
import { NostrEvent } from "applesauce-core/helpers/event";
|
|
3
|
+
import { ChannelMetadataContent } from "../helpers/channels.js";
|
|
4
|
+
/** A model that returns a map of hidden messages Map<id, reason> */
|
|
5
|
+
export declare function ChannelHiddenModel(channel: NostrEvent, authors?: string[]): Model<Map<string, string>>;
|
|
6
|
+
/** A model that returns all messages in a channel */
|
|
7
|
+
export declare function ChannelMessagesModel(channel: NostrEvent): Model<NostrEvent[]>;
|
|
8
|
+
/** A model that returns the latest parsed metadata */
|
|
9
|
+
export declare function ChannelMetadataModel(channel: NostrEvent): Model<ChannelMetadataContent | undefined>;
|
|
10
|
+
/** A model that returns a map of muted users Map<pubkey, reason> */
|
|
11
|
+
export declare function ChannelMutedModel(channel: NostrEvent, authors?: string[]): Model<Map<string, string>>;
|