@fedify/botkit 0.3.0-dev.108
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 +661 -0
- package/README.md +75 -0
- package/dist/bot-impl.d.ts +111 -0
- package/dist/bot-impl.d.ts.map +1 -0
- package/dist/bot-impl.js +602 -0
- package/dist/bot-impl.js.map +1 -0
- package/dist/bot-impl.test.d.ts +2 -0
- package/dist/bot-impl.test.js +1642 -0
- package/dist/bot-impl.test.js.map +1 -0
- package/dist/bot.d.ts +270 -0
- package/dist/bot.d.ts.map +1 -0
- package/dist/bot.js +118 -0
- package/dist/bot.js.map +1 -0
- package/dist/bot.test.d.ts +2 -0
- package/dist/bot.test.js +80 -0
- package/dist/bot.test.js.map +1 -0
- package/dist/components/Layout.d.ts +26 -0
- package/dist/components/Layout.d.ts.map +1 -0
- package/dist/components/Layout.js +36 -0
- package/dist/components/Layout.js.map +1 -0
- package/dist/components/Message.d.ts +21 -0
- package/dist/components/Message.d.ts.map +1 -0
- package/dist/components/Message.js +99 -0
- package/dist/components/Message.js.map +1 -0
- package/dist/components/Message.test.d.ts +2 -0
- package/dist/components/Message.test.js +32 -0
- package/dist/components/Message.test.js.map +1 -0
- package/dist/deno.js +73 -0
- package/dist/deno.js.map +1 -0
- package/dist/emoji.d.ts +87 -0
- package/dist/emoji.d.ts.map +1 -0
- package/dist/emoji.js +37 -0
- package/dist/emoji.js.map +1 -0
- package/dist/emoji.test.d.ts +2 -0
- package/dist/emoji.test.js +109 -0
- package/dist/emoji.test.js.map +1 -0
- package/dist/events.d.ts +110 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +4 -0
- package/dist/follow-impl.d.ts +23 -0
- package/dist/follow-impl.d.ts.map +1 -0
- package/dist/follow-impl.js +51 -0
- package/dist/follow-impl.js.map +1 -0
- package/dist/follow-impl.test.d.ts +2 -0
- package/dist/follow-impl.test.js +110 -0
- package/dist/follow-impl.test.js.map +1 -0
- package/dist/follow.d.ts +44 -0
- package/dist/follow.d.ts.map +1 -0
- package/dist/follow.js +4 -0
- package/dist/message-impl.d.ts +54 -0
- package/dist/message-impl.d.ts.map +1 -0
- package/dist/message-impl.js +439 -0
- package/dist/message-impl.js.map +1 -0
- package/dist/message-impl.test.d.ts +2 -0
- package/dist/message-impl.test.js +519 -0
- package/dist/message-impl.test.js.map +1 -0
- package/dist/message.d.ts +223 -0
- package/dist/message.d.ts.map +1 -0
- package/dist/message.js +8 -0
- package/dist/mod.d.ts +13 -0
- package/dist/mod.js +13 -0
- package/dist/pages.d.ts +20 -0
- package/dist/pages.d.ts.map +1 -0
- package/dist/pages.js +361 -0
- package/dist/pages.js.map +1 -0
- package/dist/reaction.d.ts +90 -0
- package/dist/reaction.d.ts.map +1 -0
- package/dist/reaction.js +7 -0
- package/dist/repository.d.ts +323 -0
- package/dist/repository.d.ts.map +1 -0
- package/dist/repository.js +483 -0
- package/dist/repository.js.map +1 -0
- package/dist/repository.test.d.ts +2 -0
- package/dist/repository.test.js +336 -0
- package/dist/repository.test.js.map +1 -0
- package/dist/session-impl.d.ts +32 -0
- package/dist/session-impl.d.ts.map +1 -0
- package/dist/session-impl.js +195 -0
- package/dist/session-impl.js.map +1 -0
- package/dist/session-impl.test.d.ts +20 -0
- package/dist/session-impl.test.d.ts.map +1 -0
- package/dist/session-impl.test.js +464 -0
- package/dist/session-impl.test.js.map +1 -0
- package/dist/session.d.ts +139 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +4 -0
- package/dist/text.d.ts +391 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +640 -0
- package/dist/text.js.map +1 -0
- package/dist/text.test.d.ts +2 -0
- package/dist/text.test.js +473 -0
- package/dist/text.test.js.map +1 -0
- package/package.json +137 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pages.js","names":["properties: Record<string, string>","nextLink: URL | undefined","bot: BotImpl<unknown>","ctx: Context<unknown>","options: GetPostsOptions","lastPost: Announce | Create | undefined","nextPost: Object | undefined","post: Create | Announce","context: Context<unknown>","hashtag?: string","hashtag: string"],"sources":["../src/pages.tsx"],"sourcesContent":["// BotKit by Fedify: A framework for creating ActivityPub bots\n// Copyright (C) 2025 Hong Minhee <https://hongminhee.org/>\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as\n// published by the Free Software Foundation, either version 3 of the\n// License, or (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see <https://www.gnu.org/licenses/>.\n/** @jsx react-jsx */\n/** @jsxImportSource hono/jsx */\nimport type { Context } from \"@fedify/fedify/federation\";\nimport {\n type Announce,\n type Create,\n getActorHandle,\n Hashtag,\n Image,\n Link,\n type Object,\n PUBLIC_COLLECTION,\n} from \"@fedify/fedify/vocab\";\nimport { Hono } from \"hono\";\nimport { decode } from \"html-entities\";\nimport type { BotImpl } from \"./bot-impl.ts\";\nimport { Layout } from \"./components/Layout.tsx\";\nimport { Message } from \"./components/Message.tsx\";\nimport { getMessageClass, isMessageObject, textXss } from \"./message-impl.ts\";\nimport type { MessageClass } from \"./message.ts\";\nimport type { Uuid } from \"./repository.ts\";\n\nexport interface Bindings {\n readonly bot: BotImpl<unknown>;\n readonly contextData: unknown;\n}\n\nexport interface Env {\n readonly Bindings: Bindings;\n}\n\nexport const app = new Hono<Env>();\n\napp.get(\"/\", async (c) => {\n const { bot } = c.env;\n const ctx = bot.federation.createContext(c.req.raw, c.env.contextData);\n const session = bot.getSession(ctx);\n const url = new URL(c.req.url);\n const handle = `@${bot.username}@${url.host}`;\n const icon = bot.icon instanceof Image\n ? bot.icon.url instanceof Link ? bot.icon.url.href : bot.icon.url\n : bot.icon;\n const iconWidth = bot.icon instanceof Image ? bot.icon.width : null;\n const iconHeight = bot.icon instanceof Image ? bot.icon.height : null;\n const image = bot.image instanceof Image\n ? bot.image.url instanceof Link ? bot.image.url.href : bot.image.url\n : bot.image;\n const imageWidth = bot.image instanceof Image ? bot.image.width : null;\n const imageHeight = bot.image instanceof Image ? bot.image.height : null;\n const followersCount = await bot.repository.countFollowers();\n const summaryChunks = bot.summary?.getHtml(session);\n const postsCount = await bot.repository.countMessages();\n const summary = summaryChunks == null\n ? null\n : (await Array.fromAsync(summaryChunks)).join(\"\");\n const properties: Record<string, string> = {};\n for (const name in bot.properties) {\n const value = bot.properties[name];\n const valueHtml = (await Array.fromAsync(value.getHtml(session))).join(\"\");\n properties[name] = valueHtml;\n }\n const offset = c.req.query(\"offset\");\n const { posts: messages, nextPost } = await getPosts(\n bot,\n ctx,\n offset ? { offset: Temporal.Instant.from(offset) } : {},\n );\n const activityLink = ctx.getActorUri(bot.identifier);\n const feedLink = new URL(\"/feed.xml\", url);\n let nextLink: URL | undefined;\n if (nextPost?.published != null) {\n nextLink = new URL(\"/\", url);\n nextLink.searchParams.set(\"offset\", nextPost.published.toString());\n }\n return c.html(\n <Layout\n bot={bot}\n host={url.host}\n activityLink={activityLink}\n feedLink={feedLink}\n >\n <header class=\"container\">\n {image && (\n <img\n src={image.href}\n width={imageWidth ?? undefined}\n height={imageHeight ?? undefined}\n alt={image instanceof Image\n ? image.name?.toString() ?? undefined\n : undefined}\n style=\"width: 100%; margin-bottom: 1em;\"\n />\n )}\n <hgroup>\n {icon && (\n <img\n src={icon.href}\n width={iconWidth ?? undefined}\n height={iconHeight ?? undefined}\n style=\"float: left; margin-right: 1em; height: 72;\"\n />\n )}\n <h1>\n <a href=\"/\">{bot.name ?? bot.username}</a>\n </h1>\n <p>\n <span style=\"user-select: all;\">{handle}</span> ·{\" \"}\n <a\n href=\"/feed.xml\"\n rel=\"alternate\"\n type=\"application/atom+xml\"\n title=\"Atom feed\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={18}\n height={18}\n viewBox=\"0 0 16 16\"\n aria-label=\"Atom feed\"\n >\n <path\n fill=\"currentColor\"\n d=\"M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm1.5 2.5c5.523 0 10 4.477 10 10a1 1 0 1 1-2 0a8 8 0 0 0-8-8a1 1 0 0 1 0-2m0 4a6 6 0 0 1 6 6a1 1 0 1 1-2 0a4 4 0 0 0-4-4a1 1 0 0 1 0-2m.5 7a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3\"\n >\n </path>\n </svg>\n </a>{\" \"}\n ·{\" \"}\n <span>\n {followersCount === 1\n ? `1 follower`\n : `${followersCount.toLocaleString(\"en\")} followers`}\n </span>{\" \"}\n ·{\" \"}\n <span>\n {postsCount === 1\n ? `1 post`\n : `${postsCount.toLocaleString(\"en\")} posts`}\n </span>\n {\" \"}\n </p>\n </hgroup>\n {summary &&\n (\n <div\n dangerouslySetInnerHTML={{ __html: summary }}\n />\n )}\n {globalThis.Object.keys(properties).length > 0 && (\n <table>\n <tbody>\n {globalThis.Object.entries(properties).map(([name, value]) => (\n <tr>\n <th scope=\"row\" style=\"width: 1%; white-space: nowrap;\">\n <strong>{name}</strong>\n </th>\n <td\n dangerouslySetInnerHTML={{ __html: value }}\n />\n </tr>\n ))}\n </tbody>\n </table>\n )}\n </header>\n <main class=\"container\">\n {messages.map((message) => (\n <Message message={message} session={session} />\n ))}\n </main>\n <footer class=\"container\">\n <nav style=\"display: block; text-align: end;\">\n {nextLink && (\n <a rel=\"next\" href={nextLink.href}>\n Older posts →\n </a>\n )}\n </nav>\n </footer>\n </Layout>,\n {\n headers: {\n Link:\n `<${activityLink.href}>; rel=\"alternate\"; type=\"application/activity+json\", ` +\n `<${feedLink.href}>; rel=\"alternate\"; type=\"application/atom+xml\"` +\n (nextLink\n ? `, <${nextLink.href}>; rel=\"next\"; type=\"text/html\"`\n : \"\"),\n },\n },\n );\n});\n\napp.get(\"/tags/:hashtag\", async (c) => {\n const hashtag = c.req.param(\"hashtag\");\n const { bot } = c.env;\n const url = new URL(c.req.url);\n const ctx = bot.federation.createContext(c.req.raw, c.env.contextData);\n const session = bot.getSession(ctx);\n const offset = c.req.query(\"offset\");\n const { posts, nextPost } = await getPosts(bot, ctx, {\n hashtag,\n offset: offset == null ? undefined : Temporal.Instant.from(offset),\n });\n let nextLink: URL | undefined;\n if (nextPost?.published != null) {\n nextLink = new URL(`/tags/${encodeURIComponent(hashtag)}`, url);\n nextLink.searchParams.set(\"offset\", nextPost.published.toString());\n }\n return c.html(\n <Layout bot={bot} host={url.host} title={`#${hashtag}`}>\n <header class=\"container\">\n <h1>#{hashtag}</h1>\n </header>\n <main class=\"container\">\n {posts.map((message) => (\n <Message message={message} session={session} />\n ))}\n </main>\n <footer class=\"container\">\n <nav style=\"display: block; text-align: end;\">\n {nextLink && (\n <a rel=\"next\" href={nextLink.href}>Older posts →</a>\n )}\n </nav>\n </footer>\n </Layout>,\n {\n headers: nextLink == null ? {} : {\n Link: `<${nextLink.href}>; rel=\"next\"; type=\"text/html\"`,\n },\n },\n );\n});\n\napp.get(\"/message/:id\", async (c) => {\n const id = c.req.param(\"id\");\n const { bot } = c.env;\n const url = new URL(c.req.url);\n const ctx = bot.federation.createContext(c.req.raw, c.env.contextData);\n const session = bot.getSession(ctx);\n const post = await bot.repository.getMessage(id as Uuid);\n if (post == null || !isPublic(post)) return c.notFound();\n const message = await post.getObject(ctx);\n if (message == null || !isMessageObject(message)) return c.notFound();\n const activityLink = ctx.getObjectUri<MessageClass>(\n getMessageClass(message),\n { id },\n );\n const feedLink = new URL(\"/feed.xml\", url);\n let title = message.name;\n if (title == null) {\n title = message.summary ?? message.content;\n if (title != null) {\n title = decode(textXss.process(title.toString()));\n }\n }\n return c.html(\n <Layout\n bot={bot}\n host={url.host}\n activityLink={activityLink}\n feedLink={feedLink}\n title={title?.toString() ?? undefined}\n >\n <main class=\"container\">\n <Message message={message} session={session} />\n </main>\n </Layout>,\n {\n headers: {\n Link:\n `<${activityLink.href}>; rel=\"alternate\"; type=\"application/activity+json\", ` +\n `<${feedLink.href}>; rel=\"alternate\"; type=\"application/atom+xml\"`,\n },\n },\n );\n});\n\napp.get(\"/feed.xml\", async (c) => {\n const { bot } = c.env;\n const url = new URL(c.req.url);\n const ctx = bot.federation.createContext(c.req.raw, c.env.contextData);\n const session = bot.getSession(ctx);\n const { posts } = await getPosts(bot, ctx, { window: 30 });\n const botName = bot.name ?? bot.username;\n const canonicalUrl = new URL(\"/feed.xml\", url);\n const profileUrl = new URL(\"/\", url);\n const actorUrl = ctx.getActorUri(bot.identifier);\n c.header(\n \"Link\",\n `<${actorUrl.href}>; rel=\"alternate\"; type=\"application/activity+json\", ` +\n `<${profileUrl.href}>; rel=\"alternate\"; type=\"text/html\"`,\n );\n const response = await c.render(\n <feed xmlns=\"http://www.w3.org/2005/Atom\">\n <id>{canonicalUrl.href}</id>\n <link rel=\"self\" type=\"application/atom+xml\" href={canonicalUrl.href} />\n <link rel=\"alternate\" type=\"text/html\" href={profileUrl.href} />\n <link\n rel=\"alternate\"\n type=\"application/activity+json\"\n href={actorUrl.href}\n />\n <title>{botName} (@{bot.username}@{url.host})</title>\n <author>\n <name>{botName}</name>\n <uri>{profileUrl.href}</uri>\n </author>\n {posts.length > 0 && (\n <updated>\n {(posts[0].updated ?? posts[0].published)?.toString()}\n </updated>\n )}\n {posts.map(async (post) => {\n const activityUrl = post.id;\n if (activityUrl == null) return undefined;\n const permalink =\n (post.url instanceof Link ? post.url.href : post.url) ?? activityUrl;\n const author = post.attributionId?.href === session.actorId?.href\n ? await session.getActor()\n : await post.getAttribution({\n documentLoader: ctx.documentLoader,\n contextLoader: ctx.contextLoader,\n suppressError: true,\n });\n const authorName = author?.name ?? author?.preferredUsername ??\n (author == null ? undefined : await getActorHandle(author));\n const authorUrl =\n (author?.url instanceof Link ? author.url.href : author?.url) ??\n author?.id;\n const updated = post.updated ?? post.published;\n let title = post.name;\n if (title == null) {\n title = post.summary ?? post.content;\n if (title != null) {\n title = decode(textXss.process(title.toString()));\n }\n }\n return (\n <entry>\n <id>{permalink.href}</id>\n <link rel=\"alternate\" type=\"text/html\" href={permalink.href} />\n <link\n rel=\"alternate\"\n type=\"application/activity+json\"\n href={activityUrl.href}\n />\n {authorName &&\n (\n <author>\n <name>{authorName}</name>\n {authorUrl &&\n <uri>{authorUrl.href}</uri>}\n </author>\n )}\n {post.published && (\n <published>{post.published.toString()}</published>\n )}\n {updated && <updated>{updated.toString()}</updated>}\n {title && <title>{title}</title>}\n {post.summary && (\n <summary type=\"html\">{post.summary.toString()}</summary>\n )}\n {post.content && (\n <content type=\"html\">{post.content.toString()}</content>\n )}\n </entry>\n );\n })}\n </feed>,\n );\n response.headers.set(\"Content-Type\", \"application/atom+xml; charset=utf-8\");\n return response;\n});\n\ninterface GetPostsOptions {\n readonly hashtag?: string;\n readonly offset?: Temporal.Instant;\n readonly window?: number;\n}\n\nasync function getPosts(\n bot: BotImpl<unknown>,\n ctx: Context<unknown>,\n options: GetPostsOptions = {},\n): Promise<{ posts: MessageClass[]; nextPost?: Object }> {\n const { offset, window = 15 } = options;\n let posts = await Array.fromAsync(\n bot.repository.getMessages({\n order: \"newest\",\n until: offset,\n limit: window * 2,\n }),\n );\n let lastPost: Announce | Create | undefined = posts[posts.length - 1];\n posts = posts.slice(0, posts.length - 1);\n posts = posts.filter(isPublic);\n if (options.hashtag != null) {\n const taggedPosts = [];\n for (const post of posts) {\n if (await hasHashtag(ctx, post, options.hashtag)) {\n taggedPosts.push(post);\n }\n }\n posts = taggedPosts;\n }\n while (lastPost != null && posts.length < window) {\n const limit = (window - posts.length) * 2;\n const until = lastPost.published ??\n (await lastPost.getObject(ctx))?.published ??\n undefined;\n if (until == null) break;\n const nextPosts = bot.repository.getMessages({\n order: \"newest\",\n until,\n limit,\n });\n let i = 0;\n lastPost = undefined;\n for await (const post of nextPosts) {\n if (\n isPublic(post) && await hasHashtag(ctx, post, options.hashtag) &&\n posts.length < window + 1\n ) posts.push(post);\n lastPost = post;\n i++;\n }\n if (i < limit) break;\n }\n const nextPost: Object | undefined = await posts[window]?.getObject(ctx) ??\n undefined;\n posts = posts.slice(0, window);\n const messages = (await Promise.all(posts.map((p) => p.getObject(ctx))))\n .filter(isMessageObject);\n return { posts: messages, nextPost };\n}\n\nfunction isPublic(post: Create | Announce): boolean {\n return post.toIds.some((url) => url.href === PUBLIC_COLLECTION.href) ||\n post.ccIds.some((url) => url.href === PUBLIC_COLLECTION.href);\n}\n\nasync function hasHashtag(\n context: Context<unknown>,\n post: Create | Announce,\n hashtag?: string,\n): Promise<boolean> {\n if (hashtag == null) return true;\n hashtag = normalizeHashtag(hashtag);\n const object = await post.getObject(context);\n if (object == null) return false;\n for await (const tag of object.getTags(context)) {\n if (\n tag instanceof Hashtag && tag.name != null &&\n normalizeHashtag(tag.name.toString()) === hashtag\n ) {\n return true;\n }\n }\n return false;\n}\n\nfunction normalizeHashtag(hashtag: string): string {\n return hashtag\n .toLowerCase()\n .trimStart()\n .replace(/^#/, \"\")\n .trim()\n .replace(/\\s+/g, \"\");\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { Temporal, toTemporalInstant } from "@js-temporal/polyfill";
|
|
2
|
+
Date.prototype.toTemporalInstant = toTemporalInstant;
|
|
3
|
+
import { Message, MessageClass } from "./message.js";
|
|
4
|
+
import { Emoji } from "./emoji.js";
|
|
5
|
+
import { Actor, Actor as Actor$1, Emoji as Emoji$1, EmojiReact, EmojiReact as EmojiReact$1, Like as Like$1, Like as RawLike } from "@fedify/fedify/vocab";
|
|
6
|
+
|
|
7
|
+
//#region src/reaction.d.ts
|
|
8
|
+
/**
|
|
9
|
+
* A like of a message. It is a thin wrapper around a `Like`, which is
|
|
10
|
+
* a Fedify object.
|
|
11
|
+
* @typeParam TContextData The type of the context data.
|
|
12
|
+
*/
|
|
13
|
+
interface Like<TContextData> {
|
|
14
|
+
/**
|
|
15
|
+
* The underlying raw `Like` activity.
|
|
16
|
+
*/
|
|
17
|
+
readonly raw: Like$1;
|
|
18
|
+
/**
|
|
19
|
+
* The URI of the like activity.
|
|
20
|
+
*/
|
|
21
|
+
readonly id: URL;
|
|
22
|
+
/**
|
|
23
|
+
* The actor who liked the message.
|
|
24
|
+
*/
|
|
25
|
+
readonly actor: Actor$1;
|
|
26
|
+
/**
|
|
27
|
+
* The message that was liked.
|
|
28
|
+
*/
|
|
29
|
+
readonly message: Message<MessageClass, TContextData>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* An authorized like of a message. Usually it is a like that the bot
|
|
33
|
+
* itself made.
|
|
34
|
+
* @typeParam TContextData The type of the context data.
|
|
35
|
+
*/
|
|
36
|
+
interface AuthorizedLike<TContextData> extends Like<TContextData> {
|
|
37
|
+
/**
|
|
38
|
+
* Undoes the like.
|
|
39
|
+
*
|
|
40
|
+
* If the like is already undone, this method does nothing.
|
|
41
|
+
*/
|
|
42
|
+
unlike(): Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* An emoji reaction to a message. It is a thin wrapper around an
|
|
46
|
+
* `EmojiReact`, which is a Fedify object.
|
|
47
|
+
* @typeParam TContextData The type of the context data.
|
|
48
|
+
* @since 0.2.0
|
|
49
|
+
*/
|
|
50
|
+
interface Reaction<TContextData> {
|
|
51
|
+
/**
|
|
52
|
+
* The underlying raw `Like` or `EmojiReact` activity.
|
|
53
|
+
*/
|
|
54
|
+
readonly raw: Like$1 | EmojiReact$1;
|
|
55
|
+
/**
|
|
56
|
+
* The URI of the reaction activity.
|
|
57
|
+
*/
|
|
58
|
+
readonly id: URL;
|
|
59
|
+
/**
|
|
60
|
+
* The actor who reacted to the message.
|
|
61
|
+
*/
|
|
62
|
+
readonly actor: Actor$1;
|
|
63
|
+
/**
|
|
64
|
+
* The message that was reacted.
|
|
65
|
+
*/
|
|
66
|
+
readonly message: Message<MessageClass, TContextData>;
|
|
67
|
+
/**
|
|
68
|
+
* The emoji that was used in the reaction. It can be either a Unicode emoji
|
|
69
|
+
* or a custom emoji.
|
|
70
|
+
*/
|
|
71
|
+
readonly emoji: Emoji | Emoji$1;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* An authorized emoji reaction to a message. Usually it is a reaction
|
|
75
|
+
* that the bot itself made.
|
|
76
|
+
* @typeParam TContextData The type of the context data.
|
|
77
|
+
* @since 0.2.0
|
|
78
|
+
*/
|
|
79
|
+
interface AuthorizedReaction<TContextData> extends Reaction<TContextData> {
|
|
80
|
+
/**
|
|
81
|
+
* Undoes the reaction.
|
|
82
|
+
*
|
|
83
|
+
* If the reaction is already undone, this method does nothing.
|
|
84
|
+
*/
|
|
85
|
+
unreact(): Promise<void>;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=reaction.d.ts.map
|
|
88
|
+
//#endregion
|
|
89
|
+
export { Actor, AuthorizedLike, AuthorizedReaction, EmojiReact, Like, RawLike, Reaction };
|
|
90
|
+
//# sourceMappingURL=reaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reaction.d.ts","names":[],"sources":["../src/reaction.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;AA8BiB,UAAA,IAAI,CAAA,YAAA,CAAA,CAAA;EAAA;;;EASH,SAKA,GAAA,EAVF,MAUE;EAAK;;;EAKI,SAAA,EAAA,EAVZ,GAUY;EAQV;;;EAAsD,SAM3D,KAAA,EAnBM,OAmBN;EAAO;AANuC;AAe1D;EAAyB,SAAA,OAAA,EAvBL,OAuBK,CAvBG,YAuBH,EAvBiB,YAuBjB,CAAA;;;;;;;AAmBL,UAlCH,cAkCG,CAAA,YAAA,CAAA,SAlCkC,IAkClC,CAlCuC,YAkCvC,CAAA,CAAA;EAAO;;AAMU;AASrC;;EAAmC,MAChB,EAAA,EA5CP,OA4CO,CAAA,IAAA,CAAA;;;AAAD;;;;;UAnCD;;;;gBAID,SAAU;;;;eAKX;;;;kBAKG;;;;oBAKE,QAAQ,cAAc;;;;;kBAMxB,QAAQ;;;;;;;;UAST,yCACP,SAAS;;;;;;aAMN"}
|
package/dist/reaction.js
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import { Temporal, toTemporalInstant } from "@js-temporal/polyfill";
|
|
2
|
+
Date.prototype.toTemporalInstant = toTemporalInstant;
|
|
3
|
+
import { KvKey, KvKey as KvKey$1, KvStore, KvStore as KvStore$1 } from "@fedify/fedify/federation";
|
|
4
|
+
import { Actor, Announce, Announce as Announce$1, Create, Create as Create$1, Follow } from "@fedify/fedify/vocab";
|
|
5
|
+
|
|
6
|
+
//#region src/repository.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* A UUID (universally unique identifier).
|
|
9
|
+
*/
|
|
10
|
+
type Uuid = ReturnType<typeof crypto.randomUUID>;
|
|
11
|
+
/**
|
|
12
|
+
* A repository for storing bot data.
|
|
13
|
+
*/
|
|
14
|
+
interface Repository {
|
|
15
|
+
/**
|
|
16
|
+
* Sets the key pairs of the bot actor.
|
|
17
|
+
* @param keyPairs The key pairs to set.
|
|
18
|
+
*/
|
|
19
|
+
setKeyPairs(keyPairs: CryptoKeyPair[]): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Gets the key pairs of the bot actor.
|
|
22
|
+
* @returns The key pairs of the bot actor. If the key pairs do not exist,
|
|
23
|
+
* `undefined` will be returned.
|
|
24
|
+
*/
|
|
25
|
+
getKeyPairs(): Promise<CryptoKeyPair[] | undefined>;
|
|
26
|
+
/**
|
|
27
|
+
* Adds a message to the repository.
|
|
28
|
+
* @param id The UUID of the message.
|
|
29
|
+
* @param activity The activity to add.
|
|
30
|
+
*/
|
|
31
|
+
addMessage(id: Uuid, activity: Create$1 | Announce$1): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Updates a message in the repository.
|
|
34
|
+
* @param id The UUID of the message.
|
|
35
|
+
* @param updater The function to update the message. The function will be
|
|
36
|
+
* called with the existing message, and the return value will
|
|
37
|
+
* be the new message. If the function returns a promise, the
|
|
38
|
+
* promise will be awaited. If the function returns either
|
|
39
|
+
* `undefined` or a promise that resolves to `undefined`,
|
|
40
|
+
* the message will not be updated. If the message does not
|
|
41
|
+
* exist, the updater will not be called.
|
|
42
|
+
* @returns `true` if the message was updated, `false` if the message does not
|
|
43
|
+
* exist.
|
|
44
|
+
*/
|
|
45
|
+
updateMessage(id: Uuid, updater: (existing: Create$1 | Announce$1) => Create$1 | Announce$1 | undefined | Promise<Create$1 | Announce$1 | undefined>): Promise<boolean>;
|
|
46
|
+
/**
|
|
47
|
+
* Removes a message from the repository.
|
|
48
|
+
* @param id The UUID of the message to remove.
|
|
49
|
+
* @returns The removed activity. If the message does not exist, `undefined`
|
|
50
|
+
* will be returned.
|
|
51
|
+
*/
|
|
52
|
+
removeMessage(id: Uuid): Promise<Create$1 | Announce$1 | undefined>;
|
|
53
|
+
/**
|
|
54
|
+
* Gets messages from the repository.
|
|
55
|
+
* @param options The options for getting messages.
|
|
56
|
+
* @returns An async iterable of message activities.
|
|
57
|
+
*/
|
|
58
|
+
getMessages(options?: RepositoryGetMessagesOptions): AsyncIterable<Create$1 | Announce$1>;
|
|
59
|
+
/**
|
|
60
|
+
* Gets a message from the repository.
|
|
61
|
+
* @param id The UUID of the message to get.
|
|
62
|
+
* @returns The message activity, or `undefined` if the message does not
|
|
63
|
+
* exist.
|
|
64
|
+
*/
|
|
65
|
+
getMessage(id: Uuid): Promise<Create$1 | Announce$1 | undefined>;
|
|
66
|
+
/**
|
|
67
|
+
* Counts the number of messages in the repository.
|
|
68
|
+
* @returns The number of messages in the repository.
|
|
69
|
+
*/
|
|
70
|
+
countMessages(): Promise<number>;
|
|
71
|
+
/**
|
|
72
|
+
* Adds a follower to the repository.
|
|
73
|
+
* @param followId The URL of the follow request.
|
|
74
|
+
* @param follower The actor who follows the bot.
|
|
75
|
+
*/
|
|
76
|
+
addFollower(followId: URL, follower: Actor): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Removes a follower from the repository.
|
|
79
|
+
* @param followId The URL of the follow request.
|
|
80
|
+
* @param followerId The ID of the actor to remove.
|
|
81
|
+
* @returns The removed actor. If the follower does not exist or the follow
|
|
82
|
+
* request is not about the follower, `undefined` will be returned.
|
|
83
|
+
*/
|
|
84
|
+
removeFollower(followId: URL, followerId: URL): Promise<Actor | undefined>;
|
|
85
|
+
/**
|
|
86
|
+
* Checks if the repository has a follower.
|
|
87
|
+
* @param followerId The ID of the follower to check.
|
|
88
|
+
* @returns `true` if the repository has the follower, `false` otherwise.
|
|
89
|
+
*/
|
|
90
|
+
hasFollower(followerId: URL): Promise<boolean>;
|
|
91
|
+
/**
|
|
92
|
+
* Gets followers from the repository.
|
|
93
|
+
* @param options The options for getting followers.
|
|
94
|
+
* @returns An async iterable of actors who follow the bot.
|
|
95
|
+
*/
|
|
96
|
+
getFollowers(options?: RepositoryGetFollowersOptions): AsyncIterable<Actor>;
|
|
97
|
+
/**
|
|
98
|
+
* Counts the number of followers in the repository.
|
|
99
|
+
* @returns The number of followers in the repository.
|
|
100
|
+
*/
|
|
101
|
+
countFollowers(): Promise<number>;
|
|
102
|
+
/**
|
|
103
|
+
* Adds a sent follow request to the repository.
|
|
104
|
+
* @param id The UUID of the follow request.
|
|
105
|
+
* @param follow The follow activity to add.
|
|
106
|
+
*/
|
|
107
|
+
addSentFollow(id: Uuid, follow: Follow): Promise<void>;
|
|
108
|
+
/**
|
|
109
|
+
* Removes a sent follow request from the repository.
|
|
110
|
+
* @param id The UUID of the follow request to remove.
|
|
111
|
+
* @returns The removed follow activity. If the follow request does not
|
|
112
|
+
* exist, `undefined` will be returned.
|
|
113
|
+
*/
|
|
114
|
+
removeSentFollow(id: Uuid): Promise<Follow | undefined>;
|
|
115
|
+
/**
|
|
116
|
+
* Gets a sent follow request from the repository.
|
|
117
|
+
* @param id The UUID of the follow request to get.
|
|
118
|
+
* @returns The `Follow` activity, or `undefined` if the follow request does
|
|
119
|
+
* not exist.
|
|
120
|
+
*/
|
|
121
|
+
getSentFollow(id: Uuid): Promise<Follow | undefined>;
|
|
122
|
+
/**
|
|
123
|
+
* Adds a followee to the repository.
|
|
124
|
+
* @param followeeId The ID of the followee to add.
|
|
125
|
+
* @param follow The follow activity to add.
|
|
126
|
+
*/
|
|
127
|
+
addFollowee(followeeId: URL, follow: Follow): Promise<void>;
|
|
128
|
+
/**
|
|
129
|
+
* Removes a followee from the repository.
|
|
130
|
+
* @param followeeId The ID of the followee to remove.
|
|
131
|
+
* @returns The `Follow` activity that was removed. If the followee does not
|
|
132
|
+
* exist, `undefined` will be returned.
|
|
133
|
+
*/
|
|
134
|
+
removeFollowee(followeeId: URL): Promise<Follow | undefined>;
|
|
135
|
+
/**
|
|
136
|
+
* Gets a followee from the repository.
|
|
137
|
+
* @param followeeId The ID of the followee to get.
|
|
138
|
+
* @returns The `Follow` activity, or `undefined` if the followee does not
|
|
139
|
+
* exist.
|
|
140
|
+
*/
|
|
141
|
+
getFollowee(followeeId: URL): Promise<Follow | undefined>;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Options for getting messages from the repository.
|
|
145
|
+
*/
|
|
146
|
+
interface RepositoryGetMessagesOptions {
|
|
147
|
+
/**
|
|
148
|
+
* The order of the messages. If omitted, `"newest"` will be used.
|
|
149
|
+
* @default `"newest"`
|
|
150
|
+
*/
|
|
151
|
+
readonly order?: "oldest" | "newest";
|
|
152
|
+
/**
|
|
153
|
+
* The timestamp to get messages created at or before this time.
|
|
154
|
+
* If omitted, no limit will be applied.
|
|
155
|
+
*/
|
|
156
|
+
readonly until?: Temporal.Instant;
|
|
157
|
+
/**
|
|
158
|
+
* The timestamp to get messages created at or after this time.
|
|
159
|
+
* If omitted, no limit will be applied.
|
|
160
|
+
*/
|
|
161
|
+
readonly since?: Temporal.Instant;
|
|
162
|
+
/**
|
|
163
|
+
* The maximum number of messages to get. If omitted, no limit will be
|
|
164
|
+
* applied.
|
|
165
|
+
*/
|
|
166
|
+
readonly limit?: number;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Options for getting followers from the repository.
|
|
170
|
+
*/
|
|
171
|
+
interface RepositoryGetFollowersOptions {
|
|
172
|
+
/**
|
|
173
|
+
* The offset of the followers to get. If omitted, 0 will be used.
|
|
174
|
+
* @default `0`
|
|
175
|
+
*/
|
|
176
|
+
readonly offset?: number;
|
|
177
|
+
/**
|
|
178
|
+
* The limit of the followers to get. If omitted, no limit will be applied.
|
|
179
|
+
*/
|
|
180
|
+
readonly limit?: number;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* The prefixes for key-value store keys used by the bot.
|
|
184
|
+
*/
|
|
185
|
+
interface KvStoreRepositoryPrefixes {
|
|
186
|
+
/**
|
|
187
|
+
* The key prefix used for storing the key pairs of the bot actor.
|
|
188
|
+
* @default `["_botkit", "keyPairs"]`
|
|
189
|
+
*/
|
|
190
|
+
readonly keyPairs: KvKey$1;
|
|
191
|
+
/**
|
|
192
|
+
* The key prefix used for storing published messages.
|
|
193
|
+
* @default `["_botkit", "messages"]`
|
|
194
|
+
*/
|
|
195
|
+
readonly messages: KvKey$1;
|
|
196
|
+
/**
|
|
197
|
+
* The key prefix used for storing followers.
|
|
198
|
+
* @default `["_botkit", "followers"]`
|
|
199
|
+
*/
|
|
200
|
+
readonly followers: KvKey$1;
|
|
201
|
+
/**
|
|
202
|
+
* The key prefix used for storing incoming follow requests.
|
|
203
|
+
* @default `["_botkit", "followRequests"]`
|
|
204
|
+
*/
|
|
205
|
+
readonly followRequests: KvKey$1;
|
|
206
|
+
/**
|
|
207
|
+
* The key prefix used for storing followees.
|
|
208
|
+
* @default `["_botkit", "followees"]`
|
|
209
|
+
*/
|
|
210
|
+
readonly followees: KvKey$1;
|
|
211
|
+
/**
|
|
212
|
+
* The key prefix used for storing outgoing follow requests.
|
|
213
|
+
* @default `["_botkit", "follows"]`
|
|
214
|
+
*/
|
|
215
|
+
readonly follows: KvKey$1;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* A repository for storing bot data using a key-value store.
|
|
219
|
+
*/
|
|
220
|
+
declare class KvRepository implements Repository {
|
|
221
|
+
readonly kv: KvStore$1;
|
|
222
|
+
readonly prefixes: KvStoreRepositoryPrefixes;
|
|
223
|
+
/**
|
|
224
|
+
* Creates a new key-value store repository.
|
|
225
|
+
* @param kv The key-value store to use.
|
|
226
|
+
* @param prefixes The prefixes for key-value store keys.
|
|
227
|
+
*/
|
|
228
|
+
constructor(kv: KvStore$1, prefixes?: KvStoreRepositoryPrefixes);
|
|
229
|
+
setKeyPairs(keyPairs: CryptoKeyPair[]): Promise<void>;
|
|
230
|
+
getKeyPairs(): Promise<CryptoKeyPair[] | undefined>;
|
|
231
|
+
addMessage(id: Uuid, activity: Create$1 | Announce$1): Promise<void>;
|
|
232
|
+
updateMessage(id: Uuid, updater: (existing: Create$1 | Announce$1) => Create$1 | Announce$1 | undefined | Promise<Create$1 | Announce$1 | undefined>): Promise<boolean>;
|
|
233
|
+
removeMessage(id: Uuid): Promise<Create$1 | Announce$1 | undefined>;
|
|
234
|
+
getMessages(options?: RepositoryGetMessagesOptions): AsyncIterable<Create$1 | Announce$1>;
|
|
235
|
+
getMessage(id: Uuid): Promise<Create$1 | Announce$1 | undefined>;
|
|
236
|
+
countMessages(): Promise<number>;
|
|
237
|
+
addFollower(followRequestId: URL, follower: Actor): Promise<void>;
|
|
238
|
+
removeFollower(followRequestId: URL, actorId: URL): Promise<Actor | undefined>;
|
|
239
|
+
hasFollower(followerId: URL): Promise<boolean>;
|
|
240
|
+
getFollowers(options?: RepositoryGetFollowersOptions): AsyncIterable<Actor>;
|
|
241
|
+
countFollowers(): Promise<number>;
|
|
242
|
+
addSentFollow(id: Uuid, follow: Follow): Promise<void>;
|
|
243
|
+
removeSentFollow(id: Uuid): Promise<Follow | undefined>;
|
|
244
|
+
getSentFollow(id: Uuid): Promise<Follow | undefined>;
|
|
245
|
+
addFollowee(followeeId: URL, follow: Follow): Promise<void>;
|
|
246
|
+
removeFollowee(followeeId: URL): Promise<Follow | undefined>;
|
|
247
|
+
getFollowee(followeeId: URL): Promise<Follow | undefined>;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* A repository for storing bot data in memory. This repository is not
|
|
251
|
+
* persistent and is only suitable for testing or development.
|
|
252
|
+
*/
|
|
253
|
+
declare class MemoryRepository implements Repository {
|
|
254
|
+
keyPairs?: CryptoKeyPair[];
|
|
255
|
+
messages: Map<Uuid, Create$1 | Announce$1>;
|
|
256
|
+
followers: Map<string, Actor>;
|
|
257
|
+
followRequests: Record<string, string>;
|
|
258
|
+
sentFollows: Record<string, Follow>;
|
|
259
|
+
followees: Record<string, Follow>;
|
|
260
|
+
setKeyPairs(keyPairs: CryptoKeyPair[]): Promise<void>;
|
|
261
|
+
getKeyPairs(): Promise<CryptoKeyPair[] | undefined>;
|
|
262
|
+
addMessage(id: Uuid, activity: Create$1 | Announce$1): Promise<void>;
|
|
263
|
+
updateMessage(id: Uuid, updater: (existing: Create$1 | Announce$1) => Create$1 | Announce$1 | undefined | Promise<Create$1 | Announce$1 | undefined>): Promise<boolean>;
|
|
264
|
+
removeMessage(id: Uuid): Promise<Create$1 | Announce$1 | undefined>;
|
|
265
|
+
getMessages(options?: RepositoryGetMessagesOptions): AsyncIterable<Create$1 | Announce$1>;
|
|
266
|
+
getMessage(id: Uuid): Promise<Create$1 | Announce$1 | undefined>;
|
|
267
|
+
countMessages(): Promise<number>;
|
|
268
|
+
addFollower(followId: URL, follower: Actor): Promise<void>;
|
|
269
|
+
removeFollower(followId: URL, followerId: URL): Promise<Actor | undefined>;
|
|
270
|
+
hasFollower(followerId: URL): Promise<boolean>;
|
|
271
|
+
getFollowers(options?: RepositoryGetFollowersOptions): AsyncIterable<Actor>;
|
|
272
|
+
countFollowers(): Promise<number>;
|
|
273
|
+
addSentFollow(id: Uuid, follow: Follow): Promise<void>;
|
|
274
|
+
removeSentFollow(id: Uuid): Promise<Follow | undefined>;
|
|
275
|
+
getSentFollow(id: Uuid): Promise<Follow | undefined>;
|
|
276
|
+
addFollowee(followeeId: URL, follow: Follow): Promise<void>;
|
|
277
|
+
removeFollowee(followeeId: URL): Promise<Follow | undefined>;
|
|
278
|
+
getFollowee(followeeId: URL): Promise<Follow | undefined>;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* A repository decorator that adds an in-memory cache layer on top of another
|
|
282
|
+
* repository. This is useful for improving performance by reducing the number
|
|
283
|
+
* of accesses to the underlying persistent storage, but it increases memory
|
|
284
|
+
* usage. The cache is not persistent and will be lost when the process exits.
|
|
285
|
+
*
|
|
286
|
+
* Note: List operations like `getMessages` and `getFollowers`, and count
|
|
287
|
+
* operations like `countMessages` and `countFollowers` are not cached and
|
|
288
|
+
* always delegate to the underlying repository.
|
|
289
|
+
*/
|
|
290
|
+
declare class MemoryCachedRepository implements Repository {
|
|
291
|
+
private underlying;
|
|
292
|
+
private cache;
|
|
293
|
+
/**
|
|
294
|
+
* Creates a new memory-cached repository.
|
|
295
|
+
* @param underlying The underlying repository to cache.
|
|
296
|
+
* @param cache An optional `MemoryRepository` instance to use as the cache.
|
|
297
|
+
* If not provided, a new one will be created internally.
|
|
298
|
+
*/
|
|
299
|
+
constructor(underlying: Repository, cache?: MemoryRepository);
|
|
300
|
+
setKeyPairs(keyPairs: CryptoKeyPair[]): Promise<void>;
|
|
301
|
+
getKeyPairs(): Promise<CryptoKeyPair[] | undefined>;
|
|
302
|
+
addMessage(id: Uuid, activity: Create$1 | Announce$1): Promise<void>;
|
|
303
|
+
updateMessage(id: Uuid, updater: (existing: Create$1 | Announce$1) => Create$1 | Announce$1 | undefined | Promise<Create$1 | Announce$1 | undefined>): Promise<boolean>;
|
|
304
|
+
removeMessage(id: Uuid): Promise<Create$1 | Announce$1 | undefined>;
|
|
305
|
+
getMessages(options?: RepositoryGetMessagesOptions): AsyncIterable<Create$1 | Announce$1>;
|
|
306
|
+
getMessage(id: Uuid): Promise<Create$1 | Announce$1 | undefined>;
|
|
307
|
+
countMessages(): Promise<number>;
|
|
308
|
+
addFollower(followId: URL, follower: Actor): Promise<void>;
|
|
309
|
+
removeFollower(followId: URL, followerId: URL): Promise<Actor | undefined>;
|
|
310
|
+
hasFollower(followerId: URL): Promise<boolean>;
|
|
311
|
+
getFollowers(options?: RepositoryGetFollowersOptions): AsyncIterable<Actor>;
|
|
312
|
+
countFollowers(): Promise<number>;
|
|
313
|
+
addSentFollow(id: Uuid, follow: Follow): Promise<void>;
|
|
314
|
+
removeSentFollow(id: Uuid): Promise<Follow | undefined>;
|
|
315
|
+
getSentFollow(id: Uuid): Promise<Follow | undefined>;
|
|
316
|
+
addFollowee(followeeId: URL, follow: Follow): Promise<void>;
|
|
317
|
+
removeFollowee(followeeId: URL): Promise<Follow | undefined>;
|
|
318
|
+
getFollowee(followeeId: URL): Promise<Follow | undefined>;
|
|
319
|
+
}
|
|
320
|
+
//# sourceMappingURL=repository.d.ts.map
|
|
321
|
+
//#endregion
|
|
322
|
+
export { Announce, Create, KvKey, KvRepository, KvStore, KvStoreRepositoryPrefixes, MemoryCachedRepository, MemoryRepository, Repository, RepositoryGetFollowersOptions, RepositoryGetMessagesOptions, Uuid };
|
|
323
|
+
//# sourceMappingURL=repository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.d.ts","names":[],"sources":["../src/repository.ts"],"sourcesContent":[],"mappings":"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"}
|