@fedify/botkit 0.3.0-dev.119 → 0.3.0-dev.125
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/dist/components/Message.d.ts +2 -2
- package/dist/deno.js +3 -2
- package/dist/deno.js.map +1 -1
- package/dist/message-impl.d.ts +1 -1
- package/dist/message-impl.d.ts.map +1 -1
- package/dist/message-impl.js.map +1 -1
- package/dist/pages.d.ts +2 -2
- package/dist/session-impl.js +1 -1
- package/dist/session-impl.js.map +1 -1
- package/dist/session-impl.test.d.ts.map +1 -1
- package/dist/session-impl.test.js +9 -0
- package/dist/session-impl.test.js.map +1 -1
- package/package.json +2 -2
|
@@ -2,7 +2,7 @@ import { Temporal, toTemporalInstant } from "@js-temporal/polyfill";
|
|
|
2
2
|
Date.prototype.toTemporalInstant = toTemporalInstant;
|
|
3
3
|
import { MessageClass } from "../message.js";
|
|
4
4
|
import { Session } from "../session.js";
|
|
5
|
-
import * as
|
|
5
|
+
import * as hono_utils_html0 from "hono/utils/html";
|
|
6
6
|
|
|
7
7
|
//#region src/components/Message.d.ts
|
|
8
8
|
interface MessageProps {
|
|
@@ -12,7 +12,7 @@ interface MessageProps {
|
|
|
12
12
|
declare function Message({
|
|
13
13
|
session,
|
|
14
14
|
message
|
|
15
|
-
}: MessageProps): Promise<
|
|
15
|
+
}: MessageProps): Promise<hono_utils_html0.HtmlEscapedString>;
|
|
16
16
|
declare function renderCustomEmojis(html: string, emojis: Record<string, string>): string;
|
|
17
17
|
//# sourceMappingURL=Message.d.ts.map
|
|
18
18
|
|
package/dist/deno.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
//#region deno.json
|
|
6
6
|
var name = "@fedify/botkit";
|
|
7
|
-
var version = "0.3.0-dev.
|
|
7
|
+
var version = "0.3.0-dev.125+e95bf3e4";
|
|
8
8
|
var license = "AGPL-3.0-only";
|
|
9
9
|
var unstable = ["kv", "temporal"];
|
|
10
10
|
var exports = {
|
|
@@ -21,7 +21,7 @@ var exports = {
|
|
|
21
21
|
"./text": "./src/text.ts"
|
|
22
22
|
};
|
|
23
23
|
var imports = {
|
|
24
|
-
"@fedify/fedify": "jsr:@fedify/fedify
|
|
24
|
+
"@fedify/fedify": "jsr:@fedify/fedify@1.8.1-dev.1262+8e4bd2e7",
|
|
25
25
|
"@fedify/markdown-it-hashtag": "jsr:@fedify/markdown-it-hashtag@^0.3.0",
|
|
26
26
|
"@fedify/markdown-it-mention": "jsr:@fedify/markdown-it-mention@^0.3.0",
|
|
27
27
|
"@logtape/logtape": "jsr:@logtape/logtape@^1.0.0",
|
|
@@ -41,6 +41,7 @@ var exclude = [
|
|
|
41
41
|
".vscode",
|
|
42
42
|
"dist",
|
|
43
43
|
"docs",
|
|
44
|
+
"junit.xml",
|
|
44
45
|
"src/css"
|
|
45
46
|
];
|
|
46
47
|
var fmt = { "exclude": [
|
package/dist/deno.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deno.js","names":[],"sources":["../deno.json"],"sourcesContent":["{\n \"name\": \"@fedify/botkit\",\n \"version\": \"0.3.0-dev.
|
|
1
|
+
{"version":3,"file":"deno.js","names":[],"sources":["../deno.json"],"sourcesContent":["{\n \"name\": \"@fedify/botkit\",\n \"version\": \"0.3.0-dev.125+e95bf3e4\",\n \"license\": \"AGPL-3.0-only\",\n \"unstable\": [\n \"kv\",\n \"temporal\"\n ],\n \"exports\": {\n \".\": \"./src/mod.ts\",\n \"./bot\": \"./src/bot.ts\",\n \"./emoji\": \"./src/emoji.ts\",\n \"./events\": \"./src/events.ts\",\n \"./follow\": \"./src/follow.ts\",\n \"./message\": \"./src/message.ts\",\n \"./poll\": \"./src/poll.ts\",\n \"./reaction\": \"./src/reaction.ts\",\n \"./repository\": \"./src/repository.ts\",\n \"./session\": \"./src/session.ts\",\n \"./text\": \"./src/text.ts\"\n },\n \"imports\": {\n \"@fedify/fedify\": \"jsr:@fedify/fedify@1.8.1-dev.1262+8e4bd2e7\",\n \"@fedify/markdown-it-hashtag\": \"jsr:@fedify/markdown-it-hashtag@^0.3.0\",\n \"@fedify/markdown-it-mention\": \"jsr:@fedify/markdown-it-mention@^0.3.0\",\n \"@logtape/logtape\": \"jsr:@logtape/logtape@^1.0.0\",\n \"@phensley/language-tag\": \"npm:@phensley/language-tag@^1.12.2\",\n \"hono\": \"jsr:@hono/hono@^4.8.2\",\n \"html-entities\": \"npm:html-entities@^2.6.0\",\n \"markdown-it\": \"npm:markdown-it@^14.1.0\",\n \"mime-db\": \"npm:mime-db@^1.54.0\",\n \"tsdown\": \"npm:tsdown@^0.12.8\",\n \"uuid\": \"npm:uuid@^11.1.0\",\n \"x-forwarded-fetch\": \"jsr:@hongminhee/x-forwarded-fetch@^0.2.0\",\n \"xss\": \"npm:xss@^1.0.15\"\n },\n \"nodeModulesDir\": \"none\",\n \"exclude\": [\n \".github\",\n \".vscode\",\n \"dist\",\n \"docs\",\n \"junit.xml\",\n \"src/css\"\n ],\n \"fmt\": {\n \"exclude\": [\n \"*.md\",\n \"*.yaml\",\n \"*.yml\",\n \"src/static/*.ts\"\n ]\n },\n \"tasks\": {\n \"check\": \"deno check src/ && deno lint && deno fmt --check && deno publish --dry-run --allow-dirty && deno run scripts/check_versions.ts\",\n \"test\": \"deno test --allow-env=NODE_V8_COVERAGE,JEST_WORKER_ID --allow-net=hollo.social --parallel\",\n \"test:node\": \"pnpm install && pnpm test\",\n \"test-all\": {\n \"dependencies\": [\n \"check\",\n \"test\",\n \"test:node\"\n ]\n },\n \"coverage\": \"deno task test --coverage --clean && deno coverage --html\",\n \"hooks:install\": \"deno run --allow-read=deno.json,.git/hooks/ --allow-write=.git/hooks/ jsr:@hongminhee/deno-task-hooks\",\n \"hooks:pre-commit\": \"deno task check\"\n }\n}\n"],"mappings":";;;;;WACU;cACG;cACA;eACC,CACV,MACA,UACD;cACU;CACT,KAAK;CACL,SAAS;CACT,WAAW;CACX,YAAY;CACZ,YAAY;CACZ,aAAa;CACb,UAAU;CACV,cAAc;CACd,gBAAgB;CAChB,aAAa;CACb,UAAU;AACX;cACU;CACT,kBAAkB;CAClB,+BAA+B;CAC/B,+BAA+B;CAC/B,oBAAoB;CACpB,0BAA0B;CAC1B,QAAQ;CACR,iBAAiB;CACjB,eAAe;CACf,WAAW;CACX,UAAU;CACV,QAAQ;CACR,qBAAqB;CACrB,OAAO;AACR;qBACiB;cACP;CACT;CACA;CACA;CACA;CACA;CACA;AACD;UACM,EACL,WAAW;CACT;CACA;CACA;CACA;AACD,EACF;YACQ;CACP,SAAS;CACT,QAAQ;CACR,aAAa;CACb,YAAY,EACV,gBAAgB;EACd;EACA;EACA;CACD,EACF;CACD,YAAY;CACZ,iBAAiB;CACjB,oBAAoB;AACrB;mBAnEH;;;;;;;;;;;AAoEC"}
|
package/dist/message-impl.d.ts
CHANGED
|
@@ -43,7 +43,7 @@ declare class AuthorizedMessageImpl<T extends MessageClass, TContextData> extend
|
|
|
43
43
|
delete(): Promise<void>;
|
|
44
44
|
}
|
|
45
45
|
declare const textXss: any;
|
|
46
|
-
declare function createMessage<T extends MessageClass, TContextData>(raw: T, session: SessionImpl<TContextData>, cachedObjects: Record<string, Object$1>, replyTarget
|
|
46
|
+
declare function createMessage<T extends MessageClass, TContextData>(raw: T, session: SessionImpl<TContextData>, cachedObjects: Record<string, Object$1>, replyTarget: Message<MessageClass, TContextData> | undefined, quote: Message<MessageClass, TContextData> | undefined, authorized: true): Promise<AuthorizedMessage<T, TContextData>>;
|
|
47
47
|
declare function createMessage<T extends MessageClass, TContextData>(raw: T, session: SessionImpl<TContextData>, cachedObjects: Record<string, Object$1>, replyTarget?: Message<MessageClass, TContextData>, quote?: Message<MessageClass, TContextData>, authorized?: boolean): Promise<Message<T, TContextData>>;
|
|
48
48
|
declare function getMessageVisibility(toIds: URL[], ccIds: URL[], actor: Actor, mentionedActorIds?: Set<string>): MessageVisibility;
|
|
49
49
|
declare function isQuoteLink(tag: Link): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-impl.d.ts","names":[],"sources":["../src/message-impl.ts"],"sourcesContent":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"message-impl.d.ts","names":[],"sources":["../src/message-impl.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/message-impl.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-impl.js","names":["value: unknown","value: MessageClass","session: SessionImpl<TContextData>","message: Omit<\n Message<T, TContextData>,\n \"delete\" | \"reply\" | \"share\" | \"like\" | \"react\"\n >","text: Text<\"block\", TContextData>","options?:\n | SessionPublishOptions<TContextData>\n | SessionPublishOptionsWithClass<MessageClass, TContextData>","options: MessageShareOptions","RawLike","emoji: Emoji | CustomEmoji | DeferredCustomEmoji<TContextData>","existingMentions: readonly Actor[]","mentionedActors: Actor[]","update: Update | undefined","mentionedActorIds: URL[]","hashtags: Hashtag[]","cachedObjects: Record<string, Object>","promises: Promise<Object | null>[]","updated","mentionedActorIds: Set<string>","raw: T","replyTarget?: Message<MessageClass, TContextData>","quoteTarget?: Message<MessageClass, TContextData>","authorized: boolean","mentions: Actor[]","quoteLinks: Link[]","attachments: Document[]","rt: Link | Object | null","cls: new (values: any) => T","quoteUrl: URL | null","qt: Object | null","toIds: URL[]","ccIds: URL[]","actor: Actor","mentionedActorIds?: Set<string>","tag: Link","params: Record<string, string>"],"sources":["../src/message-impl.ts"],"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/>.\nimport { LanguageString } from \"@fedify/fedify/runtime\";\nimport {\n type Actor,\n Announce,\n Article,\n ChatMessage,\n Create,\n Delete,\n Document,\n type Emoji as CustomEmoji,\n EmojiReact,\n Hashtag,\n isActor,\n Like as RawLike,\n Link,\n Mention,\n Note,\n type Object,\n PUBLIC_COLLECTION,\n Question,\n Tombstone,\n Undo,\n Update,\n} from \"@fedify/fedify/vocab\";\nimport type { LanguageTag } from \"@phensley/language-tag\";\nimport { decode } from \"html-entities\";\nimport { v7 as uuidv7 } from \"uuid\";\nimport xss from \"xss\";\nimport type { DeferredCustomEmoji, Emoji } from \"./emoji.ts\";\nimport type {\n AuthorizedMessage,\n AuthorizedSharedMessage,\n Message,\n MessageClass,\n MessageShareOptions,\n MessageVisibility,\n} from \"./message.ts\";\nimport type { AuthorizedLike, AuthorizedReaction } from \"./reaction.ts\";\nimport type { Uuid } from \"./repository.ts\";\nimport type { SessionImpl } from \"./session-impl.ts\";\nimport type {\n SessionPublishOptions,\n SessionPublishOptionsWithClass,\n} from \"./session.ts\";\nimport type { Text } from \"./text.ts\";\n\nexport const messageClasses = [Article, ChatMessage, Note, Question];\n\nexport function isMessageObject(value: unknown): value is MessageClass {\n return messageClasses.some((cls) => value instanceof cls);\n}\n\nexport function getMessageClass(\n value: MessageClass,\n): (typeof Article | typeof ChatMessage | typeof Note | typeof Question) & {\n typeId: URL;\n} {\n return value instanceof Article\n ? Article\n : value instanceof ChatMessage\n ? ChatMessage\n : value instanceof Note\n ? Note\n : Question;\n}\n\nexport class MessageImpl<T extends MessageClass, TContextData>\n implements Message<T, TContextData> {\n readonly session: SessionImpl<TContextData>;\n raw: T;\n readonly id: URL;\n readonly actor: Actor;\n readonly visibility: MessageVisibility;\n readonly language?: LanguageTag | undefined;\n text: string;\n html: string;\n readonly replyTarget?: Message<MessageClass, TContextData> | undefined;\n readonly quoteTarget?: Message<MessageClass, TContextData> | undefined;\n mentions: readonly Actor[];\n hashtags: readonly Hashtag[];\n readonly attachments: readonly Document[];\n readonly published?: Temporal.Instant;\n updated?: Temporal.Instant;\n\n constructor(\n session: SessionImpl<TContextData>,\n message: Omit<\n Message<T, TContextData>,\n \"delete\" | \"reply\" | \"share\" | \"like\" | \"react\"\n >,\n ) {\n this.session = session;\n this.raw = message.raw;\n this.id = message.id;\n this.actor = message.actor;\n this.visibility = message.visibility;\n this.language = message.language;\n this.text = message.text;\n this.html = message.html;\n this.replyTarget = message.replyTarget;\n this.quoteTarget = message.quoteTarget;\n this.mentions = message.mentions;\n this.hashtags = message.hashtags;\n this.attachments = message.attachments;\n this.published = message.published;\n this.updated = message.updated;\n }\n\n reply(\n text: Text<\"block\", TContextData>,\n options?: SessionPublishOptions<TContextData>,\n ): Promise<AuthorizedMessage<Note, TContextData>>;\n reply<T extends MessageClass>(\n text: Text<\"block\", TContextData>,\n options?: SessionPublishOptionsWithClass<T, TContextData> | undefined,\n ): Promise<AuthorizedMessage<T, TContextData>>;\n reply(\n text: Text<\"block\", TContextData>,\n options?:\n | SessionPublishOptions<TContextData>\n | SessionPublishOptionsWithClass<MessageClass, TContextData>,\n ): Promise<AuthorizedMessage<MessageClass, TContextData>> {\n return this.session.publish(text, {\n visibility: this.visibility === \"unknown\" ? \"direct\" : this.visibility,\n ...options,\n replyTarget: this,\n });\n }\n\n async share(\n options: MessageShareOptions = {},\n ): Promise<AuthorizedSharedMessage<T, TContextData>> {\n const published = new Date();\n const id = uuidv7({ msecs: +published }) as Uuid;\n const visibility = options.visibility ?? this.visibility;\n const originalActor = this.actor.id == null ? [] : [this.actor.id];\n const uri = this.session.context.getObjectUri(Announce, { id });\n const announce = new Announce({\n id: uri,\n actor: this.session.context.getActorUri(this.session.bot.identifier),\n published: published.toTemporalInstant(),\n object: this.id,\n tos: visibility === \"public\"\n ? [PUBLIC_COLLECTION]\n : visibility === \"unlisted\" || visibility === \"followers\"\n ? [\n this.session.context.getFollowersUri(this.session.bot.identifier),\n ]\n : [],\n ccs: visibility === \"public\"\n ? [\n this.session.context.getFollowersUri(this.session.bot.identifier),\n ...originalActor,\n ]\n : visibility === \"unlisted\"\n ? [PUBLIC_COLLECTION, ...originalActor]\n : originalActor,\n });\n await this.session.bot.repository.addMessage(id, announce);\n await this.session.context.sendActivity(\n this.session.bot,\n \"followers\",\n announce,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n },\n );\n await this.session.context.sendActivity(\n this.session.bot,\n this.actor,\n announce,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n fanout: \"skip\",\n },\n );\n const actor = announce.actorId?.href === this.session.actorId.href\n ? await this.session.getActor()\n : await announce.getActor(this.session.context);\n if (actor == null) throw new TypeError(\"The actor is required.\");\n return {\n raw: announce,\n id: uri,\n actor,\n visibility,\n original: this,\n unshare: async () => {\n await this.session.bot.repository.removeMessage(id);\n const undo = new Undo({\n id: new URL(\"#delete\", uri),\n actor: this.session.context.getActorUri(\n this.session.bot.identifier,\n ),\n tos: announce.toIds,\n ccs: announce.ccIds,\n object: announce,\n });\n await this.session.context.sendActivity(\n this.session.bot,\n \"followers\",\n undo,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n },\n );\n await this.session.context.sendActivity(\n this.session.bot,\n this.actor,\n undo,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n fanout: \"skip\",\n },\n );\n },\n };\n }\n\n async like(): Promise<AuthorizedLike<TContextData>> {\n const uuid = crypto.randomUUID();\n const actor = this.session.context.getActorUri(this.session.bot.identifier);\n const id = new URL(`#like/${uuid}`, actor);\n const activity = new RawLike({\n id,\n actor,\n object: this.id,\n });\n await this.session.context.sendActivity(\n this.session.bot,\n \"followers\",\n activity,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n },\n );\n await this.session.context.sendActivity(\n this.session.bot,\n this.actor,\n activity,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n fanout: \"skip\",\n },\n );\n return {\n raw: activity,\n id,\n actor: await this.session.getActor(),\n message: this,\n unlike: async () => {\n const undo = new Undo({\n id: new URL(`#unlike/${uuid}`, actor),\n actor,\n object: activity,\n });\n await this.session.context.sendActivity(\n this.session.bot,\n \"followers\",\n undo,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n },\n );\n await this.session.context.sendActivity(\n this.session.bot,\n this.actor,\n undo,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n fanout: \"skip\",\n },\n );\n },\n };\n }\n\n async react(\n emoji: Emoji | CustomEmoji | DeferredCustomEmoji<TContextData>,\n ): Promise<AuthorizedReaction<TContextData>> {\n const uuid = crypto.randomUUID();\n const actor = this.session.context.getActorUri(this.session.bot.identifier);\n const id = new URL(`#react/${uuid}`, actor);\n if (typeof emoji === \"function\") {\n emoji = await emoji(this.session);\n }\n const activity = new EmojiReact({\n id,\n actor,\n object: this.id,\n name: typeof emoji === \"string\" ? emoji : emoji.name,\n tags: typeof emoji === \"string\" ? [] : [emoji],\n });\n await this.session.context.sendActivity(\n this.session.bot,\n \"followers\",\n activity,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n },\n );\n await this.session.context.sendActivity(\n this.session.bot,\n this.actor,\n activity,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n fanout: \"skip\",\n },\n );\n return {\n raw: activity,\n id,\n actor: await this.session.getActor(),\n message: this,\n emoji,\n unreact: async () => {\n const undo = new Undo({\n id: new URL(`#unreact/${uuid}`, actor),\n actor,\n object: activity,\n name: typeof emoji === \"string\" ? emoji : emoji.name,\n tags: typeof emoji === \"string\" ? [] : [emoji],\n });\n await this.session.context.sendActivity(\n this.session.bot,\n \"followers\",\n undo,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n },\n );\n await this.session.context.sendActivity(\n this.session.bot,\n this.actor,\n undo,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n fanout: \"skip\",\n },\n );\n },\n };\n }\n}\n\nexport class AuthorizedMessageImpl<T extends MessageClass, TContextData>\n extends MessageImpl<T, TContextData>\n implements AuthorizedMessage<T, TContextData> {\n async update(text: Text<\"block\", TContextData>): Promise<void> {\n const parsed = this.session.context.parseUri(this.id);\n if (\n parsed?.type !== \"object\" ||\n !messageClasses.some((cls) => parsed.class === cls)\n ) {\n return;\n }\n const { id } = parsed.values;\n let existingMentions: readonly Actor[] = [];\n let mentionedActors: Actor[] = [];\n let update: Update | undefined;\n const updated = await this.session.bot.repository.updateMessage(\n id as Uuid,\n async (create) => {\n if (create instanceof Announce) return;\n const message = await create.getObject(this.session.context);\n if (message == null || !isMessageObject(message)) return;\n let contentHtml = \"\";\n for await (const chunk of text.getHtml(this.session)) {\n contentHtml += chunk;\n }\n const tags = await Array.fromAsync(text.getTags(this.session));\n const mentionedActorIds: URL[] = [];\n const hashtags: Hashtag[] = [];\n for (const tag of tags) {\n if (tag instanceof Mention && tag.href != null) {\n mentionedActorIds.push(tag.href);\n } else if (tag instanceof Hashtag) {\n hashtags.push(tag);\n }\n }\n const cachedObjects: Record<string, Object> = {};\n for (const cachedObject of text.getCachedObjects()) {\n if (cachedObject.id == null) continue;\n cachedObjects[cachedObject.id.href] = cachedObject;\n }\n const documentLoader = await this.session.context.getDocumentLoader(\n this.session.bot,\n );\n const promises: Promise<Object | null>[] = [];\n for (const uri of mentionedActorIds) {\n const cachedObject = cachedObjects[uri.href];\n const promise = cachedObject == null\n ? this.session.context.lookupObject(uri, { documentLoader })\n : Promise.resolve(cachedObject);\n promises.push(promise);\n }\n const objects = await Promise.all(promises);\n mentionedActors = objects.filter(isActor);\n this.html = contentHtml;\n this.text = decode(textXss.process(contentHtml));\n existingMentions = this.mentions;\n this.mentions = mentionedActors;\n this.hashtags = hashtags;\n const updated = Temporal.Now.instant();\n this.updated = updated;\n const newMessage = message.clone({\n contents: this.language == null\n ? [contentHtml]\n : [new LanguageString(contentHtml, this.language), contentHtml],\n tags,\n tos: this.visibility === \"public\"\n ? [PUBLIC_COLLECTION, ...mentionedActorIds]\n : this.visibility === \"unlisted\" || this.visibility === \"followers\"\n ? [\n this.session.context.getFollowersUri(this.session.bot.identifier),\n ...mentionedActorIds,\n ]\n : mentionedActorIds,\n ccs: this.visibility === \"public\"\n ? [\n this.session.context.getFollowersUri(this.session.bot.identifier),\n ]\n : this.visibility === \"unlisted\"\n ? [PUBLIC_COLLECTION]\n : [],\n updated,\n });\n this.raw = newMessage as T;\n create = create.clone({ object: newMessage, updated });\n const to = create.toIds.map((url) => url.href);\n for (const url of newMessage.toIds) {\n if (!to.includes(url.href)) to.push(url.href);\n }\n const cc = create.ccIds.map((url) => url.href);\n for (const url of newMessage.ccIds) {\n if (!cc.includes(url.href)) cc.push(url.href);\n }\n update = new Update({\n id: new URL(\n `#updated/${updated.toString()}`,\n this.session.context.getObjectUri(Create, { id }),\n ),\n actors: newMessage.attributionIds,\n tos: to.map((url) => new URL(url)),\n ccs: cc.map((url) => new URL(url)),\n object: newMessage,\n updated,\n });\n return create;\n },\n );\n if (!updated || update == null) return;\n const preferSharedInbox = this.visibility === \"public\" ||\n this.visibility === \"unlisted\" || this.visibility === \"followers\";\n const excludeBaseUris = [new URL(this.session.context.origin)];\n if (preferSharedInbox) {\n await this.session.context.sendActivity(\n this.session.bot,\n \"followers\",\n update,\n { preferSharedInbox, excludeBaseUris },\n );\n }\n await this.session.context.sendActivity(\n this.session.bot,\n [...existingMentions, ...mentionedActors],\n update,\n { preferSharedInbox, excludeBaseUris },\n );\n if (this.replyTarget != null) {\n await this.session.context.sendActivity(\n this.session.bot,\n this.replyTarget.actor,\n update,\n { preferSharedInbox: true, excludeBaseUris, fanout: \"skip\" },\n );\n }\n if (this.quoteTarget != null) {\n await this.session.context.sendActivity(\n this.session.bot,\n this.quoteTarget.actor,\n update,\n { preferSharedInbox: true, excludeBaseUris, fanout: \"skip\" },\n );\n }\n }\n\n async delete(): Promise<void> {\n const parsed = this.session.context.parseUri(this.id);\n if (\n parsed?.type !== \"object\" ||\n !messageClasses.some((cls) => parsed.class === cls)\n ) {\n return;\n }\n const { id } = parsed.values;\n const create = await this.session.bot.repository.removeMessage(id as Uuid);\n if (create == null) return;\n const message = await create.getObject(this.session.context);\n if (message == null) return;\n const mentionedActorIds: Set<string> = new Set();\n for await (const tag of message.getTags(this.session.context)) {\n if (tag instanceof Mention && tag.href != null) {\n mentionedActorIds.add(tag.href.href);\n }\n }\n const promises: Promise<Object | null>[] = [];\n const documentLoader = await this.session.context.getDocumentLoader(\n this.session.bot,\n );\n for (const uri of mentionedActorIds) {\n promises.push(this.session.context.lookupObject(uri, { documentLoader }));\n }\n const mentionedActors = (await Promise.all(promises)).filter(isActor);\n const activity = new Delete({\n id: new URL(\"#delete\", this.id),\n actor: this.session.context.getActorUri(this.session.bot.identifier),\n tos: create.toIds,\n ccs: create.ccIds,\n object: new Tombstone({\n id: this.id,\n }),\n });\n const excludeBaseUris = [new URL(this.session.context.origin)];\n await this.session.context.sendActivity(\n this.session.bot,\n \"followers\",\n activity,\n { preferSharedInbox: true, excludeBaseUris },\n );\n if (mentionedActors.length > 0) {\n await this.session.context.sendActivity(\n this.session.bot,\n mentionedActors,\n activity,\n { preferSharedInbox: true, excludeBaseUris },\n );\n }\n if (this.replyTarget != null) {\n await this.session.context.sendActivity(\n this.session.bot,\n this.replyTarget.actor,\n activity,\n { preferSharedInbox: true, excludeBaseUris, fanout: \"skip\" },\n );\n }\n if (this.quoteTarget != null) {\n await this.session.context.sendActivity(\n this.session.bot,\n this.quoteTarget.actor,\n activity,\n { preferSharedInbox: true, excludeBaseUris, fanout: \"skip\" },\n );\n }\n }\n}\n\n// @ts-ignore: The `xss` module has `getDefaultWhiteList` function.\nconst allowList = xss.getDefaultWhiteList();\n// @ts-ignore: The `xss` module has `FilterXSS` class.\nconst htmlXss = new xss.FilterXSS({\n allowList: {\n ...allowList,\n a: [...allowList.a ?? [], \"class\", \"translate\"],\n },\n});\n// @ts-ignore: The `xss` module has `FilterXSS` class.\nexport const textXss = new xss.FilterXSS({\n allowList: {},\n stripIgnoreTag: true,\n});\n\nexport async function createMessage<T extends MessageClass, TContextData>(\n raw: T,\n session: SessionImpl<TContextData>,\n cachedObjects: Record<string, Object>,\n replyTarget?: Message<MessageClass, TContextData>,\n quote?: Message<MessageClass, TContextData>,\n authorized?: true,\n): Promise<AuthorizedMessage<T, TContextData>>;\nexport async function createMessage<T extends MessageClass, TContextData>(\n raw: T,\n session: SessionImpl<TContextData>,\n cachedObjects: Record<string, Object>,\n replyTarget?: Message<MessageClass, TContextData>,\n quote?: Message<MessageClass, TContextData>,\n authorized?: boolean,\n): Promise<Message<T, TContextData>>;\nexport async function createMessage<T extends MessageClass, TContextData>(\n raw: T,\n session: SessionImpl<TContextData>,\n cachedObjects: Record<string, Object>,\n replyTarget?: Message<MessageClass, TContextData>,\n quoteTarget?: Message<MessageClass, TContextData>,\n authorized: boolean = false,\n): Promise<Message<T, TContextData>> {\n if (raw.id == null) throw new TypeError(\"The raw.id is required.\");\n else if (raw.content == null) {\n throw new TypeError(\"The raw.content is required.\");\n }\n const documentLoader = await session.context.getDocumentLoader(session.bot);\n const options = {\n contextLoader: session.context.contextLoader,\n documentLoader,\n suppressError: true,\n };\n const actor = raw.attributionId?.href === session.actorId?.href\n ? await session.getActor()\n : await raw.getAttribution(options);\n if (actor == null) {\n throw new TypeError(\"The raw.attributionId is required.\");\n }\n const content = raw.content.toString();\n const text = textXss.process(content);\n const html = htmlXss.process(content);\n const mentions: Actor[] = [];\n const mentionedActorIds = new Set<string>();\n const hashtags: Hashtag[] = [];\n const quoteLinks: Link[] = [];\n for await (const tag of raw.getTags(options)) {\n if (tag instanceof Mention && tag.href != null) {\n const obj = tag.href.href === session.actorId?.href\n ? await session.getActor()\n : cachedObjects[tag.href.href] == null\n ? await session.context.lookupObject(tag.href, options)\n : cachedObjects[tag.href.href];\n if (isActor(obj)) mentions.push(obj);\n mentionedActorIds.add(tag.href.href);\n } else if (tag instanceof Hashtag) {\n hashtags.push(tag);\n } else if (tag instanceof Link && isQuoteLink(tag)) {\n quoteLinks.push(tag);\n }\n }\n const attachments: Document[] = [];\n for await (const attachment of raw.getAttachments(options)) {\n if (attachment instanceof Document) attachments.push(attachment);\n }\n if (replyTarget == null) {\n let rt: Link | Object | null;\n const parsed = session.context.parseUri(raw.replyTargetId);\n // @ts-ignore: The `class` property satisfies the `MessageClass` type.\n if (parsed?.type === \"object\" && messageClasses.includes(parsed.class)) {\n // @ts-ignore: The `class` property satisfies the `MessageClass` type.\n // deno-lint-ignore no-explicit-any\n const cls: new (values: any) => T = parsed.class;\n rt = await session.bot.dispatchMessage(\n cls,\n session.context,\n parsed.values.id,\n );\n } else {\n rt = await raw.getReplyTarget(options);\n }\n if (\n rt instanceof Article || rt instanceof ChatMessage ||\n rt instanceof Note || rt instanceof Question\n ) {\n replyTarget = await createMessage(rt, session, cachedObjects);\n }\n }\n if (quoteTarget == null) {\n let quoteUrl: URL | null = null;\n for (const quoteLink of quoteLinks) {\n if (quoteLink.href == null) continue;\n quoteUrl = quoteLink.href;\n break;\n }\n if (quoteUrl == null) quoteUrl = raw.quoteUrl;\n let qt: Object | null = null;\n const parsed = session.context.parseUri(quoteUrl);\n // @ts-ignore: The `class` property satisfies the `MessageClass` type.\n if (parsed?.type === \"object\" && messageClasses.includes(parsed.class)) {\n // @ts-ignore: The `class` property satisfies the `MessageClass` type.\n // deno-lint-ignore no-explicit-any\n const cls: new (values: any) => T = parsed.class;\n qt = await session.bot.dispatchMessage(\n cls,\n session.context,\n parsed.values.id,\n );\n } else if (quoteUrl != null) {\n qt = await session.context.lookupObject(quoteUrl, options);\n }\n if (\n qt instanceof Article || qt instanceof ChatMessage ||\n qt instanceof Note || qt instanceof Question\n ) {\n quoteTarget = await createMessage(qt, session, cachedObjects);\n }\n }\n return new (authorized ? AuthorizedMessageImpl : MessageImpl)(session, {\n raw,\n id: raw.id,\n actor,\n visibility: getMessageVisibility(\n raw.toIds,\n raw.ccIds,\n actor,\n mentionedActorIds,\n ),\n language: raw.content instanceof LanguageString\n ? raw.content.language\n : undefined,\n text: decode(text),\n html,\n replyTarget,\n quoteTarget,\n mentions,\n hashtags,\n attachments,\n published: raw.published ?? undefined,\n updated: raw.updated ?? undefined,\n });\n}\n\nexport function getMessageVisibility(\n toIds: URL[],\n ccIds: URL[],\n actor: Actor,\n mentionedActorIds?: Set<string>,\n): MessageVisibility {\n const to = toIds.map((url) => url.href);\n const cc = ccIds.map((url) => url.href);\n const recipients = new Set([...to, ...cc]);\n return to.includes(PUBLIC_COLLECTION.href)\n ? \"public\"\n : cc.includes(PUBLIC_COLLECTION.href)\n ? \"unlisted\"\n : actor.followersId != null &&\n (to.includes(actor.followersId.href) ||\n cc.includes(actor.followersId.href))\n ? \"followers\"\n : recipients.size > 0 &&\n recipients.intersection(mentionedActorIds ?? new Set()).size ===\n recipients.size\n ? \"direct\"\n : \"unknown\";\n}\n\nexport function isQuoteLink(tag: Link): boolean {\n if (tag.rel === \"https://misskey-hub.net/ns#_misskey_quote\") return true;\n else if (tag.mediaType == null) return false;\n // FIXME: Properly parse the media type\n const parsed = tag.mediaType.split(\";\");\n const type = parsed[0].trim();\n if (type === \"application/activity+json\") return true;\n const params: Record<string, string> = {};\n for (let i = 1; i < parsed.length; i++) {\n const param = parsed[i].trim().split(\"=\");\n if (param.length === 2) {\n params[param[0]] = param[1].replace(/\"/g, \"\");\n }\n }\n return type === \"application/ld+json\" &&\n params.profile === \"https://www.w3.org/ns/activitystreams\";\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"message-impl.js","names":["value: unknown","value: MessageClass","session: SessionImpl<TContextData>","message: Omit<\n Message<T, TContextData>,\n \"delete\" | \"reply\" | \"share\" | \"like\" | \"react\"\n >","text: Text<\"block\", TContextData>","options?:\n | SessionPublishOptions<TContextData>\n | SessionPublishOptionsWithClass<MessageClass, TContextData>","options: MessageShareOptions","RawLike","emoji: Emoji | CustomEmoji | DeferredCustomEmoji<TContextData>","existingMentions: readonly Actor[]","mentionedActors: Actor[]","update: Update | undefined","mentionedActorIds: URL[]","hashtags: Hashtag[]","cachedObjects: Record<string, Object>","promises: Promise<Object | null>[]","updated","mentionedActorIds: Set<string>","raw: T","replyTarget?: Message<MessageClass, TContextData>","quoteTarget?: Message<MessageClass, TContextData>","authorized: boolean","mentions: Actor[]","quoteLinks: Link[]","attachments: Document[]","rt: Link | Object | null","cls: new (values: any) => T","quoteUrl: URL | null","qt: Object | null","toIds: URL[]","ccIds: URL[]","actor: Actor","mentionedActorIds?: Set<string>","tag: Link","params: Record<string, string>"],"sources":["../src/message-impl.ts"],"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/>.\nimport { LanguageString } from \"@fedify/fedify/runtime\";\nimport {\n type Actor,\n Announce,\n Article,\n ChatMessage,\n Create,\n Delete,\n Document,\n type Emoji as CustomEmoji,\n EmojiReact,\n Hashtag,\n isActor,\n Like as RawLike,\n Link,\n Mention,\n Note,\n type Object,\n PUBLIC_COLLECTION,\n Question,\n Tombstone,\n Undo,\n Update,\n} from \"@fedify/fedify/vocab\";\nimport type { LanguageTag } from \"@phensley/language-tag\";\nimport { decode } from \"html-entities\";\nimport { v7 as uuidv7 } from \"uuid\";\nimport xss from \"xss\";\nimport type { DeferredCustomEmoji, Emoji } from \"./emoji.ts\";\nimport type {\n AuthorizedMessage,\n AuthorizedSharedMessage,\n Message,\n MessageClass,\n MessageShareOptions,\n MessageVisibility,\n} from \"./message.ts\";\nimport type { AuthorizedLike, AuthorizedReaction } from \"./reaction.ts\";\nimport type { Uuid } from \"./repository.ts\";\nimport type { SessionImpl } from \"./session-impl.ts\";\nimport type {\n SessionPublishOptions,\n SessionPublishOptionsWithClass,\n} from \"./session.ts\";\nimport type { Text } from \"./text.ts\";\n\nexport const messageClasses = [Article, ChatMessage, Note, Question];\n\nexport function isMessageObject(value: unknown): value is MessageClass {\n return messageClasses.some((cls) => value instanceof cls);\n}\n\nexport function getMessageClass(\n value: MessageClass,\n): (typeof Article | typeof ChatMessage | typeof Note | typeof Question) & {\n typeId: URL;\n} {\n return value instanceof Article\n ? Article\n : value instanceof ChatMessage\n ? ChatMessage\n : value instanceof Note\n ? Note\n : Question;\n}\n\nexport class MessageImpl<T extends MessageClass, TContextData>\n implements Message<T, TContextData> {\n readonly session: SessionImpl<TContextData>;\n raw: T;\n readonly id: URL;\n readonly actor: Actor;\n readonly visibility: MessageVisibility;\n readonly language?: LanguageTag | undefined;\n text: string;\n html: string;\n readonly replyTarget?: Message<MessageClass, TContextData> | undefined;\n readonly quoteTarget?: Message<MessageClass, TContextData> | undefined;\n mentions: readonly Actor[];\n hashtags: readonly Hashtag[];\n readonly attachments: readonly Document[];\n readonly published?: Temporal.Instant;\n updated?: Temporal.Instant;\n\n constructor(\n session: SessionImpl<TContextData>,\n message: Omit<\n Message<T, TContextData>,\n \"delete\" | \"reply\" | \"share\" | \"like\" | \"react\"\n >,\n ) {\n this.session = session;\n this.raw = message.raw;\n this.id = message.id;\n this.actor = message.actor;\n this.visibility = message.visibility;\n this.language = message.language;\n this.text = message.text;\n this.html = message.html;\n this.replyTarget = message.replyTarget;\n this.quoteTarget = message.quoteTarget;\n this.mentions = message.mentions;\n this.hashtags = message.hashtags;\n this.attachments = message.attachments;\n this.published = message.published;\n this.updated = message.updated;\n }\n\n reply(\n text: Text<\"block\", TContextData>,\n options?: SessionPublishOptions<TContextData>,\n ): Promise<AuthorizedMessage<Note, TContextData>>;\n reply<T extends MessageClass>(\n text: Text<\"block\", TContextData>,\n options?: SessionPublishOptionsWithClass<T, TContextData> | undefined,\n ): Promise<AuthorizedMessage<T, TContextData>>;\n reply(\n text: Text<\"block\", TContextData>,\n options?:\n | SessionPublishOptions<TContextData>\n | SessionPublishOptionsWithClass<MessageClass, TContextData>,\n ): Promise<AuthorizedMessage<MessageClass, TContextData>> {\n return this.session.publish(text, {\n visibility: this.visibility === \"unknown\" ? \"direct\" : this.visibility,\n ...options,\n replyTarget: this,\n });\n }\n\n async share(\n options: MessageShareOptions = {},\n ): Promise<AuthorizedSharedMessage<T, TContextData>> {\n const published = new Date();\n const id = uuidv7({ msecs: +published }) as Uuid;\n const visibility = options.visibility ?? this.visibility;\n const originalActor = this.actor.id == null ? [] : [this.actor.id];\n const uri = this.session.context.getObjectUri(Announce, { id });\n const announce = new Announce({\n id: uri,\n actor: this.session.context.getActorUri(this.session.bot.identifier),\n published: published.toTemporalInstant(),\n object: this.id,\n tos: visibility === \"public\"\n ? [PUBLIC_COLLECTION]\n : visibility === \"unlisted\" || visibility === \"followers\"\n ? [\n this.session.context.getFollowersUri(this.session.bot.identifier),\n ]\n : [],\n ccs: visibility === \"public\"\n ? [\n this.session.context.getFollowersUri(this.session.bot.identifier),\n ...originalActor,\n ]\n : visibility === \"unlisted\"\n ? [PUBLIC_COLLECTION, ...originalActor]\n : originalActor,\n });\n await this.session.bot.repository.addMessage(id, announce);\n await this.session.context.sendActivity(\n this.session.bot,\n \"followers\",\n announce,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n },\n );\n await this.session.context.sendActivity(\n this.session.bot,\n this.actor,\n announce,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n fanout: \"skip\",\n },\n );\n const actor = announce.actorId?.href === this.session.actorId.href\n ? await this.session.getActor()\n : await announce.getActor(this.session.context);\n if (actor == null) throw new TypeError(\"The actor is required.\");\n return {\n raw: announce,\n id: uri,\n actor,\n visibility,\n original: this,\n unshare: async () => {\n await this.session.bot.repository.removeMessage(id);\n const undo = new Undo({\n id: new URL(\"#delete\", uri),\n actor: this.session.context.getActorUri(\n this.session.bot.identifier,\n ),\n tos: announce.toIds,\n ccs: announce.ccIds,\n object: announce,\n });\n await this.session.context.sendActivity(\n this.session.bot,\n \"followers\",\n undo,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n },\n );\n await this.session.context.sendActivity(\n this.session.bot,\n this.actor,\n undo,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n fanout: \"skip\",\n },\n );\n },\n };\n }\n\n async like(): Promise<AuthorizedLike<TContextData>> {\n const uuid = crypto.randomUUID();\n const actor = this.session.context.getActorUri(this.session.bot.identifier);\n const id = new URL(`#like/${uuid}`, actor);\n const activity = new RawLike({\n id,\n actor,\n object: this.id,\n });\n await this.session.context.sendActivity(\n this.session.bot,\n \"followers\",\n activity,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n },\n );\n await this.session.context.sendActivity(\n this.session.bot,\n this.actor,\n activity,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n fanout: \"skip\",\n },\n );\n return {\n raw: activity,\n id,\n actor: await this.session.getActor(),\n message: this,\n unlike: async () => {\n const undo = new Undo({\n id: new URL(`#unlike/${uuid}`, actor),\n actor,\n object: activity,\n });\n await this.session.context.sendActivity(\n this.session.bot,\n \"followers\",\n undo,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n },\n );\n await this.session.context.sendActivity(\n this.session.bot,\n this.actor,\n undo,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n fanout: \"skip\",\n },\n );\n },\n };\n }\n\n async react(\n emoji: Emoji | CustomEmoji | DeferredCustomEmoji<TContextData>,\n ): Promise<AuthorizedReaction<TContextData>> {\n const uuid = crypto.randomUUID();\n const actor = this.session.context.getActorUri(this.session.bot.identifier);\n const id = new URL(`#react/${uuid}`, actor);\n if (typeof emoji === \"function\") {\n emoji = await emoji(this.session);\n }\n const activity = new EmojiReact({\n id,\n actor,\n object: this.id,\n name: typeof emoji === \"string\" ? emoji : emoji.name,\n tags: typeof emoji === \"string\" ? [] : [emoji],\n });\n await this.session.context.sendActivity(\n this.session.bot,\n \"followers\",\n activity,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n },\n );\n await this.session.context.sendActivity(\n this.session.bot,\n this.actor,\n activity,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n fanout: \"skip\",\n },\n );\n return {\n raw: activity,\n id,\n actor: await this.session.getActor(),\n message: this,\n emoji,\n unreact: async () => {\n const undo = new Undo({\n id: new URL(`#unreact/${uuid}`, actor),\n actor,\n object: activity,\n name: typeof emoji === \"string\" ? emoji : emoji.name,\n tags: typeof emoji === \"string\" ? [] : [emoji],\n });\n await this.session.context.sendActivity(\n this.session.bot,\n \"followers\",\n undo,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n },\n );\n await this.session.context.sendActivity(\n this.session.bot,\n this.actor,\n undo,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(this.session.context.origin)],\n fanout: \"skip\",\n },\n );\n },\n };\n }\n}\n\nexport class AuthorizedMessageImpl<T extends MessageClass, TContextData>\n extends MessageImpl<T, TContextData>\n implements AuthorizedMessage<T, TContextData> {\n async update(text: Text<\"block\", TContextData>): Promise<void> {\n const parsed = this.session.context.parseUri(this.id);\n if (\n parsed?.type !== \"object\" ||\n !messageClasses.some((cls) => parsed.class === cls)\n ) {\n return;\n }\n const { id } = parsed.values;\n let existingMentions: readonly Actor[] = [];\n let mentionedActors: Actor[] = [];\n let update: Update | undefined;\n const updated = await this.session.bot.repository.updateMessage(\n id as Uuid,\n async (create) => {\n if (create instanceof Announce) return;\n const message = await create.getObject(this.session.context);\n if (message == null || !isMessageObject(message)) return;\n let contentHtml = \"\";\n for await (const chunk of text.getHtml(this.session)) {\n contentHtml += chunk;\n }\n const tags = await Array.fromAsync(text.getTags(this.session));\n const mentionedActorIds: URL[] = [];\n const hashtags: Hashtag[] = [];\n for (const tag of tags) {\n if (tag instanceof Mention && tag.href != null) {\n mentionedActorIds.push(tag.href);\n } else if (tag instanceof Hashtag) {\n hashtags.push(tag);\n }\n }\n const cachedObjects: Record<string, Object> = {};\n for (const cachedObject of text.getCachedObjects()) {\n if (cachedObject.id == null) continue;\n cachedObjects[cachedObject.id.href] = cachedObject;\n }\n const documentLoader = await this.session.context.getDocumentLoader(\n this.session.bot,\n );\n const promises: Promise<Object | null>[] = [];\n for (const uri of mentionedActorIds) {\n const cachedObject = cachedObjects[uri.href];\n const promise = cachedObject == null\n ? this.session.context.lookupObject(uri, { documentLoader })\n : Promise.resolve(cachedObject);\n promises.push(promise);\n }\n const objects = await Promise.all(promises);\n mentionedActors = objects.filter(isActor);\n this.html = contentHtml;\n this.text = decode(textXss.process(contentHtml));\n existingMentions = this.mentions;\n this.mentions = mentionedActors;\n this.hashtags = hashtags;\n const updated = Temporal.Now.instant();\n this.updated = updated;\n const newMessage = message.clone({\n contents: this.language == null\n ? [contentHtml]\n : [new LanguageString(contentHtml, this.language), contentHtml],\n tags,\n tos: this.visibility === \"public\"\n ? [PUBLIC_COLLECTION, ...mentionedActorIds]\n : this.visibility === \"unlisted\" || this.visibility === \"followers\"\n ? [\n this.session.context.getFollowersUri(this.session.bot.identifier),\n ...mentionedActorIds,\n ]\n : mentionedActorIds,\n ccs: this.visibility === \"public\"\n ? [\n this.session.context.getFollowersUri(this.session.bot.identifier),\n ]\n : this.visibility === \"unlisted\"\n ? [PUBLIC_COLLECTION]\n : [],\n updated,\n });\n this.raw = newMessage as T;\n create = create.clone({ object: newMessage, updated });\n const to = create.toIds.map((url) => url.href);\n for (const url of newMessage.toIds) {\n if (!to.includes(url.href)) to.push(url.href);\n }\n const cc = create.ccIds.map((url) => url.href);\n for (const url of newMessage.ccIds) {\n if (!cc.includes(url.href)) cc.push(url.href);\n }\n update = new Update({\n id: new URL(\n `#updated/${updated.toString()}`,\n this.session.context.getObjectUri(Create, { id }),\n ),\n actors: newMessage.attributionIds,\n tos: to.map((url) => new URL(url)),\n ccs: cc.map((url) => new URL(url)),\n object: newMessage,\n updated,\n });\n return create;\n },\n );\n if (!updated || update == null) return;\n const preferSharedInbox = this.visibility === \"public\" ||\n this.visibility === \"unlisted\" || this.visibility === \"followers\";\n const excludeBaseUris = [new URL(this.session.context.origin)];\n if (preferSharedInbox) {\n await this.session.context.sendActivity(\n this.session.bot,\n \"followers\",\n update,\n { preferSharedInbox, excludeBaseUris },\n );\n }\n await this.session.context.sendActivity(\n this.session.bot,\n [...existingMentions, ...mentionedActors],\n update,\n { preferSharedInbox, excludeBaseUris },\n );\n if (this.replyTarget != null) {\n await this.session.context.sendActivity(\n this.session.bot,\n this.replyTarget.actor,\n update,\n { preferSharedInbox: true, excludeBaseUris, fanout: \"skip\" },\n );\n }\n if (this.quoteTarget != null) {\n await this.session.context.sendActivity(\n this.session.bot,\n this.quoteTarget.actor,\n update,\n { preferSharedInbox: true, excludeBaseUris, fanout: \"skip\" },\n );\n }\n }\n\n async delete(): Promise<void> {\n const parsed = this.session.context.parseUri(this.id);\n if (\n parsed?.type !== \"object\" ||\n !messageClasses.some((cls) => parsed.class === cls)\n ) {\n return;\n }\n const { id } = parsed.values;\n const create = await this.session.bot.repository.removeMessage(id as Uuid);\n if (create == null) return;\n const message = await create.getObject(this.session.context);\n if (message == null) return;\n const mentionedActorIds: Set<string> = new Set();\n for await (const tag of message.getTags(this.session.context)) {\n if (tag instanceof Mention && tag.href != null) {\n mentionedActorIds.add(tag.href.href);\n }\n }\n const promises: Promise<Object | null>[] = [];\n const documentLoader = await this.session.context.getDocumentLoader(\n this.session.bot,\n );\n for (const uri of mentionedActorIds) {\n promises.push(this.session.context.lookupObject(uri, { documentLoader }));\n }\n const mentionedActors = (await Promise.all(promises)).filter(isActor);\n const activity = new Delete({\n id: new URL(\"#delete\", this.id),\n actor: this.session.context.getActorUri(this.session.bot.identifier),\n tos: create.toIds,\n ccs: create.ccIds,\n object: new Tombstone({\n id: this.id,\n }),\n });\n const excludeBaseUris = [new URL(this.session.context.origin)];\n await this.session.context.sendActivity(\n this.session.bot,\n \"followers\",\n activity,\n { preferSharedInbox: true, excludeBaseUris },\n );\n if (mentionedActors.length > 0) {\n await this.session.context.sendActivity(\n this.session.bot,\n mentionedActors,\n activity,\n { preferSharedInbox: true, excludeBaseUris },\n );\n }\n if (this.replyTarget != null) {\n await this.session.context.sendActivity(\n this.session.bot,\n this.replyTarget.actor,\n activity,\n { preferSharedInbox: true, excludeBaseUris, fanout: \"skip\" },\n );\n }\n if (this.quoteTarget != null) {\n await this.session.context.sendActivity(\n this.session.bot,\n this.quoteTarget.actor,\n activity,\n { preferSharedInbox: true, excludeBaseUris, fanout: \"skip\" },\n );\n }\n }\n}\n\n// @ts-ignore: The `xss` module has `getDefaultWhiteList` function.\nconst allowList = xss.getDefaultWhiteList();\n// @ts-ignore: The `xss` module has `FilterXSS` class.\nconst htmlXss = new xss.FilterXSS({\n allowList: {\n ...allowList,\n a: [...allowList.a ?? [], \"class\", \"translate\"],\n },\n});\n// @ts-ignore: The `xss` module has `FilterXSS` class.\nexport const textXss = new xss.FilterXSS({\n allowList: {},\n stripIgnoreTag: true,\n});\n\nexport async function createMessage<T extends MessageClass, TContextData>(\n raw: T,\n session: SessionImpl<TContextData>,\n cachedObjects: Record<string, Object>,\n replyTarget: Message<MessageClass, TContextData> | undefined,\n quote: Message<MessageClass, TContextData> | undefined,\n authorized: true,\n): Promise<AuthorizedMessage<T, TContextData>>;\nexport async function createMessage<T extends MessageClass, TContextData>(\n raw: T,\n session: SessionImpl<TContextData>,\n cachedObjects: Record<string, Object>,\n replyTarget?: Message<MessageClass, TContextData>,\n quote?: Message<MessageClass, TContextData>,\n authorized?: boolean,\n): Promise<Message<T, TContextData>>;\nexport async function createMessage<T extends MessageClass, TContextData>(\n raw: T,\n session: SessionImpl<TContextData>,\n cachedObjects: Record<string, Object>,\n replyTarget?: Message<MessageClass, TContextData>,\n quoteTarget?: Message<MessageClass, TContextData>,\n authorized: boolean = false,\n): Promise<Message<T, TContextData>> {\n if (raw.id == null) throw new TypeError(\"The raw.id is required.\");\n else if (raw.content == null) {\n throw new TypeError(\"The raw.content is required.\");\n }\n const documentLoader = await session.context.getDocumentLoader(session.bot);\n const options = {\n contextLoader: session.context.contextLoader,\n documentLoader,\n suppressError: true,\n };\n const actor = raw.attributionId?.href === session.actorId?.href\n ? await session.getActor()\n : await raw.getAttribution(options);\n if (actor == null) {\n throw new TypeError(\"The raw.attributionId is required.\");\n }\n const content = raw.content.toString();\n const text = textXss.process(content);\n const html = htmlXss.process(content);\n const mentions: Actor[] = [];\n const mentionedActorIds = new Set<string>();\n const hashtags: Hashtag[] = [];\n const quoteLinks: Link[] = [];\n for await (const tag of raw.getTags(options)) {\n if (tag instanceof Mention && tag.href != null) {\n const obj = tag.href.href === session.actorId?.href\n ? await session.getActor()\n : cachedObjects[tag.href.href] == null\n ? await session.context.lookupObject(tag.href, options)\n : cachedObjects[tag.href.href];\n if (isActor(obj)) mentions.push(obj);\n mentionedActorIds.add(tag.href.href);\n } else if (tag instanceof Hashtag) {\n hashtags.push(tag);\n } else if (tag instanceof Link && isQuoteLink(tag)) {\n quoteLinks.push(tag);\n }\n }\n const attachments: Document[] = [];\n for await (const attachment of raw.getAttachments(options)) {\n if (attachment instanceof Document) attachments.push(attachment);\n }\n if (replyTarget == null) {\n let rt: Link | Object | null;\n const parsed = session.context.parseUri(raw.replyTargetId);\n // @ts-ignore: The `class` property satisfies the `MessageClass` type.\n if (parsed?.type === \"object\" && messageClasses.includes(parsed.class)) {\n // @ts-ignore: The `class` property satisfies the `MessageClass` type.\n // deno-lint-ignore no-explicit-any\n const cls: new (values: any) => T = parsed.class;\n rt = await session.bot.dispatchMessage(\n cls,\n session.context,\n parsed.values.id,\n );\n } else {\n rt = await raw.getReplyTarget(options);\n }\n if (\n rt instanceof Article || rt instanceof ChatMessage ||\n rt instanceof Note || rt instanceof Question\n ) {\n replyTarget = await createMessage(rt, session, cachedObjects);\n }\n }\n if (quoteTarget == null) {\n let quoteUrl: URL | null = null;\n for (const quoteLink of quoteLinks) {\n if (quoteLink.href == null) continue;\n quoteUrl = quoteLink.href;\n break;\n }\n if (quoteUrl == null) quoteUrl = raw.quoteUrl;\n let qt: Object | null = null;\n const parsed = session.context.parseUri(quoteUrl);\n // @ts-ignore: The `class` property satisfies the `MessageClass` type.\n if (parsed?.type === \"object\" && messageClasses.includes(parsed.class)) {\n // @ts-ignore: The `class` property satisfies the `MessageClass` type.\n // deno-lint-ignore no-explicit-any\n const cls: new (values: any) => T = parsed.class;\n qt = await session.bot.dispatchMessage(\n cls,\n session.context,\n parsed.values.id,\n );\n } else if (quoteUrl != null) {\n qt = await session.context.lookupObject(quoteUrl, options);\n }\n if (\n qt instanceof Article || qt instanceof ChatMessage ||\n qt instanceof Note || qt instanceof Question\n ) {\n quoteTarget = await createMessage(qt, session, cachedObjects);\n }\n }\n return new (authorized ? AuthorizedMessageImpl : MessageImpl)(session, {\n raw,\n id: raw.id,\n actor,\n visibility: getMessageVisibility(\n raw.toIds,\n raw.ccIds,\n actor,\n mentionedActorIds,\n ),\n language: raw.content instanceof LanguageString\n ? raw.content.language\n : undefined,\n text: decode(text),\n html,\n replyTarget,\n quoteTarget,\n mentions,\n hashtags,\n attachments,\n published: raw.published ?? undefined,\n updated: raw.updated ?? undefined,\n });\n}\n\nexport function getMessageVisibility(\n toIds: URL[],\n ccIds: URL[],\n actor: Actor,\n mentionedActorIds?: Set<string>,\n): MessageVisibility {\n const to = toIds.map((url) => url.href);\n const cc = ccIds.map((url) => url.href);\n const recipients = new Set([...to, ...cc]);\n return to.includes(PUBLIC_COLLECTION.href)\n ? \"public\"\n : cc.includes(PUBLIC_COLLECTION.href)\n ? \"unlisted\"\n : actor.followersId != null &&\n (to.includes(actor.followersId.href) ||\n cc.includes(actor.followersId.href))\n ? \"followers\"\n : recipients.size > 0 &&\n recipients.intersection(mentionedActorIds ?? new Set()).size ===\n recipients.size\n ? \"direct\"\n : \"unknown\";\n}\n\nexport function isQuoteLink(tag: Link): boolean {\n if (tag.rel === \"https://misskey-hub.net/ns#_misskey_quote\") return true;\n else if (tag.mediaType == null) return false;\n // FIXME: Properly parse the media type\n const parsed = tag.mediaType.split(\";\");\n const type = parsed[0].trim();\n if (type === \"application/activity+json\") return true;\n const params: Record<string, string> = {};\n for (let i = 1; i < parsed.length; i++) {\n const param = parsed[i].trim().split(\"=\");\n if (param.length === 2) {\n params[param[0]] = param[1].replace(/\"/g, \"\");\n }\n }\n return type === \"application/ld+json\" &&\n params.profile === \"https://www.w3.org/ns/activitystreams\";\n}\n"],"mappings":";;;;;;;;;;;AA6DA,MAAa,iBAAiB;CAAC;CAAS;CAAa;CAAM;AAAS;AAEpE,SAAgB,gBAAgBA,OAAuC;AACrE,QAAO,eAAe,KAAK,CAAC,QAAQ,iBAAiB,IAAI;AAC1D;AAED,SAAgB,gBACdC,OAGA;AACA,QAAO,iBAAiB,UACpB,UACA,iBAAiB,cACjB,cACA,iBAAiB,OACjB,OACA;AACL;AAED,IAAa,cAAb,MACsC;CACpC,AAAS;CACT;CACA,AAAS;CACT,AAAS;CACT,AAAS;CACT,AAAS;CACT;CACA;CACA,AAAS;CACT,AAAS;CACT;CACA;CACA,AAAS;CACT,AAAS;CACT;CAEA,YACEC,SACAC,SAIA;AACA,OAAK,UAAU;AACf,OAAK,MAAM,QAAQ;AACnB,OAAK,KAAK,QAAQ;AAClB,OAAK,QAAQ,QAAQ;AACrB,OAAK,aAAa,QAAQ;AAC1B,OAAK,WAAW,QAAQ;AACxB,OAAK,OAAO,QAAQ;AACpB,OAAK,OAAO,QAAQ;AACpB,OAAK,cAAc,QAAQ;AAC3B,OAAK,cAAc,QAAQ;AAC3B,OAAK,WAAW,QAAQ;AACxB,OAAK,WAAW,QAAQ;AACxB,OAAK,cAAc,QAAQ;AAC3B,OAAK,YAAY,QAAQ;AACzB,OAAK,UAAU,QAAQ;CACxB;CAUD,MACEC,MACAC,SAGwD;AACxD,SAAO,KAAK,QAAQ,QAAQ,MAAM;GAChC,YAAY,KAAK,eAAe,YAAY,WAAW,KAAK;GAC5D,GAAG;GACH,aAAa;EACd,EAAC;CACH;CAED,MAAM,MACJC,UAA+B,CAAE,GACkB;EACnD,MAAM,4BAAY,IAAI;EACtB,MAAM,KAAK,GAAO,EAAE,QAAQ,UAAW,EAAC;EACxC,MAAM,aAAa,QAAQ,cAAc,KAAK;EAC9C,MAAM,gBAAgB,KAAK,MAAM,MAAM,OAAO,CAAE,IAAG,CAAC,KAAK,MAAM,EAAG;EAClE,MAAM,MAAM,KAAK,QAAQ,QAAQ,aAAa,UAAU,EAAE,GAAI,EAAC;EAC/D,MAAM,WAAW,IAAI,SAAS;GAC5B,IAAI;GACJ,OAAO,KAAK,QAAQ,QAAQ,YAAY,KAAK,QAAQ,IAAI,WAAW;GACpE,WAAW,UAAU,mBAAmB;GACxC,QAAQ,KAAK;GACb,KAAK,eAAe,WAChB,CAAC,iBAAkB,IACnB,eAAe,cAAc,eAAe,cAC5C,CACA,KAAK,QAAQ,QAAQ,gBAAgB,KAAK,QAAQ,IAAI,WAAW,AAClE,IACC,CAAE;GACN,KAAK,eAAe,WAChB,CACA,KAAK,QAAQ,QAAQ,gBAAgB,KAAK,QAAQ,IAAI,WAAW,EACjE,GAAG,aACJ,IACC,eAAe,aACf,CAAC,mBAAmB,GAAG,aAAc,IACrC;EACL;AACD,QAAM,KAAK,QAAQ,IAAI,WAAW,WAAW,IAAI,SAAS;AAC1D,QAAM,KAAK,QAAQ,QAAQ,aACzB,KAAK,QAAQ,KACb,aACA,UACA;GACE,mBAAmB;GACnB,iBAAiB,CAAC,IAAI,IAAI,KAAK,QAAQ,QAAQ,OAAQ;EACxD,EACF;AACD,QAAM,KAAK,QAAQ,QAAQ,aACzB,KAAK,QAAQ,KACb,KAAK,OACL,UACA;GACE,mBAAmB;GACnB,iBAAiB,CAAC,IAAI,IAAI,KAAK,QAAQ,QAAQ,OAAQ;GACvD,QAAQ;EACT,EACF;EACD,MAAM,QAAQ,SAAS,SAAS,SAAS,KAAK,QAAQ,QAAQ,OAC1D,MAAM,KAAK,QAAQ,UAAU,GAC7B,MAAM,SAAS,SAAS,KAAK,QAAQ,QAAQ;AACjD,MAAI,SAAS,KAAM,OAAM,IAAI,UAAU;AACvC,SAAO;GACL,KAAK;GACL,IAAI;GACJ;GACA;GACA,UAAU;GACV,SAAS,YAAY;AACnB,UAAM,KAAK,QAAQ,IAAI,WAAW,cAAc,GAAG;IACnD,MAAM,OAAO,IAAI,KAAK;KACpB,IAAI,IAAI,IAAI,WAAW;KACvB,OAAO,KAAK,QAAQ,QAAQ,YAC1B,KAAK,QAAQ,IAAI,WAClB;KACD,KAAK,SAAS;KACd,KAAK,SAAS;KACd,QAAQ;IACT;AACD,UAAM,KAAK,QAAQ,QAAQ,aACzB,KAAK,QAAQ,KACb,aACA,MACA;KACE,mBAAmB;KACnB,iBAAiB,CAAC,IAAI,IAAI,KAAK,QAAQ,QAAQ,OAAQ;IACxD,EACF;AACD,UAAM,KAAK,QAAQ,QAAQ,aACzB,KAAK,QAAQ,KACb,KAAK,OACL,MACA;KACE,mBAAmB;KACnB,iBAAiB,CAAC,IAAI,IAAI,KAAK,QAAQ,QAAQ,OAAQ;KACvD,QAAQ;IACT,EACF;GACF;EACF;CACF;CAED,MAAM,OAA8C;EAClD,MAAM,OAAO,OAAO,YAAY;EAChC,MAAM,QAAQ,KAAK,QAAQ,QAAQ,YAAY,KAAK,QAAQ,IAAI,WAAW;EAC3E,MAAM,KAAK,IAAI,KAAK,QAAQ,KAAK,GAAG;EACpC,MAAM,WAAW,IAAIC,KAAQ;GAC3B;GACA;GACA,QAAQ,KAAK;EACd;AACD,QAAM,KAAK,QAAQ,QAAQ,aACzB,KAAK,QAAQ,KACb,aACA,UACA;GACE,mBAAmB;GACnB,iBAAiB,CAAC,IAAI,IAAI,KAAK,QAAQ,QAAQ,OAAQ;EACxD,EACF;AACD,QAAM,KAAK,QAAQ,QAAQ,aACzB,KAAK,QAAQ,KACb,KAAK,OACL,UACA;GACE,mBAAmB;GACnB,iBAAiB,CAAC,IAAI,IAAI,KAAK,QAAQ,QAAQ,OAAQ;GACvD,QAAQ;EACT,EACF;AACD,SAAO;GACL,KAAK;GACL;GACA,OAAO,MAAM,KAAK,QAAQ,UAAU;GACpC,SAAS;GACT,QAAQ,YAAY;IAClB,MAAM,OAAO,IAAI,KAAK;KACpB,IAAI,IAAI,KAAK,UAAU,KAAK,GAAG;KAC/B;KACA,QAAQ;IACT;AACD,UAAM,KAAK,QAAQ,QAAQ,aACzB,KAAK,QAAQ,KACb,aACA,MACA;KACE,mBAAmB;KACnB,iBAAiB,CAAC,IAAI,IAAI,KAAK,QAAQ,QAAQ,OAAQ;IACxD,EACF;AACD,UAAM,KAAK,QAAQ,QAAQ,aACzB,KAAK,QAAQ,KACb,KAAK,OACL,MACA;KACE,mBAAmB;KACnB,iBAAiB,CAAC,IAAI,IAAI,KAAK,QAAQ,QAAQ,OAAQ;KACvD,QAAQ;IACT,EACF;GACF;EACF;CACF;CAED,MAAM,MACJC,OAC2C;EAC3C,MAAM,OAAO,OAAO,YAAY;EAChC,MAAM,QAAQ,KAAK,QAAQ,QAAQ,YAAY,KAAK,QAAQ,IAAI,WAAW;EAC3E,MAAM,KAAK,IAAI,KAAK,SAAS,KAAK,GAAG;AACrC,aAAW,UAAU,WACnB,SAAQ,MAAM,MAAM,KAAK,QAAQ;EAEnC,MAAM,WAAW,IAAI,WAAW;GAC9B;GACA;GACA,QAAQ,KAAK;GACb,aAAa,UAAU,WAAW,QAAQ,MAAM;GAChD,aAAa,UAAU,WAAW,CAAE,IAAG,CAAC,KAAM;EAC/C;AACD,QAAM,KAAK,QAAQ,QAAQ,aACzB,KAAK,QAAQ,KACb,aACA,UACA;GACE,mBAAmB;GACnB,iBAAiB,CAAC,IAAI,IAAI,KAAK,QAAQ,QAAQ,OAAQ;EACxD,EACF;AACD,QAAM,KAAK,QAAQ,QAAQ,aACzB,KAAK,QAAQ,KACb,KAAK,OACL,UACA;GACE,mBAAmB;GACnB,iBAAiB,CAAC,IAAI,IAAI,KAAK,QAAQ,QAAQ,OAAQ;GACvD,QAAQ;EACT,EACF;AACD,SAAO;GACL,KAAK;GACL;GACA,OAAO,MAAM,KAAK,QAAQ,UAAU;GACpC,SAAS;GACT;GACA,SAAS,YAAY;IACnB,MAAM,OAAO,IAAI,KAAK;KACpB,IAAI,IAAI,KAAK,WAAW,KAAK,GAAG;KAChC;KACA,QAAQ;KACR,aAAa,UAAU,WAAW,QAAQ,MAAM;KAChD,aAAa,UAAU,WAAW,CAAE,IAAG,CAAC,KAAM;IAC/C;AACD,UAAM,KAAK,QAAQ,QAAQ,aACzB,KAAK,QAAQ,KACb,aACA,MACA;KACE,mBAAmB;KACnB,iBAAiB,CAAC,IAAI,IAAI,KAAK,QAAQ,QAAQ,OAAQ;IACxD,EACF;AACD,UAAM,KAAK,QAAQ,QAAQ,aACzB,KAAK,QAAQ,KACb,KAAK,OACL,MACA;KACE,mBAAmB;KACnB,iBAAiB,CAAC,IAAI,IAAI,KAAK,QAAQ,QAAQ,OAAQ;KACvD,QAAQ;IACT,EACF;GACF;EACF;CACF;AACF;AAED,IAAa,wBAAb,cACU,YACsC;CAC9C,MAAM,OAAOJ,MAAkD;EAC7D,MAAM,SAAS,KAAK,QAAQ,QAAQ,SAAS,KAAK,GAAG;AACrD,MACE,QAAQ,SAAS,aAChB,eAAe,KAAK,CAAC,QAAQ,OAAO,UAAU,IAAI,CAEnD;EAEF,MAAM,EAAE,IAAI,GAAG,OAAO;EACtB,IAAIK,mBAAqC,CAAE;EAC3C,IAAIC,kBAA2B,CAAE;EACjC,IAAIC;EACJ,MAAM,UAAU,MAAM,KAAK,QAAQ,IAAI,WAAW,cAChD,IACA,OAAO,WAAW;AAChB,OAAI,kBAAkB,SAAU;GAChC,MAAM,UAAU,MAAM,OAAO,UAAU,KAAK,QAAQ,QAAQ;AAC5D,OAAI,WAAW,SAAS,gBAAgB,QAAQ,CAAE;GAClD,IAAI,cAAc;AAClB,cAAW,MAAM,SAAS,KAAK,QAAQ,KAAK,QAAQ,CAClD,gBAAe;GAEjB,MAAM,OAAO,MAAM,MAAM,UAAU,KAAK,QAAQ,KAAK,QAAQ,CAAC;GAC9D,MAAMC,oBAA2B,CAAE;GACnC,MAAMC,WAAsB,CAAE;AAC9B,QAAK,MAAM,OAAO,KAChB,KAAI,eAAe,WAAW,IAAI,QAAQ,KACxC,mBAAkB,KAAK,IAAI,KAAK;YACvB,eAAe,QACxB,UAAS,KAAK,IAAI;GAGtB,MAAMC,gBAAwC,CAAE;AAChD,QAAK,MAAM,gBAAgB,KAAK,kBAAkB,EAAE;AAClD,QAAI,aAAa,MAAM,KAAM;AAC7B,kBAAc,aAAa,GAAG,QAAQ;GACvC;GACD,MAAM,iBAAiB,MAAM,KAAK,QAAQ,QAAQ,kBAChD,KAAK,QAAQ,IACd;GACD,MAAMC,WAAqC,CAAE;AAC7C,QAAK,MAAM,OAAO,mBAAmB;IACnC,MAAM,eAAe,cAAc,IAAI;IACvC,MAAM,UAAU,gBAAgB,OAC5B,KAAK,QAAQ,QAAQ,aAAa,KAAK,EAAE,eAAgB,EAAC,GAC1D,QAAQ,QAAQ,aAAa;AACjC,aAAS,KAAK,QAAQ;GACvB;GACD,MAAM,UAAU,MAAM,QAAQ,IAAI,SAAS;AAC3C,qBAAkB,QAAQ,OAAO,QAAQ;AACzC,QAAK,OAAO;AACZ,QAAK,OAAO,OAAO,QAAQ,QAAQ,YAAY,CAAC;AAChD,sBAAmB,KAAK;AACxB,QAAK,WAAW;AAChB,QAAK,WAAW;GAChB,MAAMC,YAAU,SAAS,IAAI,SAAS;AACtC,QAAK,UAAUA;GACf,MAAM,aAAa,QAAQ,MAAM;IAC/B,UAAU,KAAK,YAAY,OACvB,CAAC,WAAY,IACb,CAAC,IAAI,eAAe,aAAa,KAAK,WAAW,WAAY;IACjE;IACA,KAAK,KAAK,eAAe,WACrB,CAAC,mBAAmB,GAAG,iBAAkB,IACzC,KAAK,eAAe,cAAc,KAAK,eAAe,cACtD,CACA,KAAK,QAAQ,QAAQ,gBAAgB,KAAK,QAAQ,IAAI,WAAW,EACjE,GAAG,iBACJ,IACC;IACJ,KAAK,KAAK,eAAe,WACrB,CACA,KAAK,QAAQ,QAAQ,gBAAgB,KAAK,QAAQ,IAAI,WAAW,AAClE,IACC,KAAK,eAAe,aACpB,CAAC,iBAAkB,IACnB,CAAE;IACN;GACD,EAAC;AACF,QAAK,MAAM;AACX,YAAS,OAAO,MAAM;IAAE,QAAQ;IAAY;GAAS,EAAC;GACtD,MAAM,KAAK,OAAO,MAAM,IAAI,CAAC,QAAQ,IAAI,KAAK;AAC9C,QAAK,MAAM,OAAO,WAAW,MAC3B,MAAK,GAAG,SAAS,IAAI,KAAK,CAAE,IAAG,KAAK,IAAI,KAAK;GAE/C,MAAM,KAAK,OAAO,MAAM,IAAI,CAAC,QAAQ,IAAI,KAAK;AAC9C,QAAK,MAAM,OAAO,WAAW,MAC3B,MAAK,GAAG,SAAS,IAAI,KAAK,CAAE,IAAG,KAAK,IAAI,KAAK;AAE/C,YAAS,IAAI,OAAO;IAClB,IAAI,IAAI,KACL,WAAW,UAAQ,UAAU,CAAC,GAC/B,KAAK,QAAQ,QAAQ,aAAa,QAAQ,EAAE,GAAI,EAAC;IAEnD,QAAQ,WAAW;IACnB,KAAK,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,KAAK;IAClC,KAAK,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,KAAK;IAClC,QAAQ;IACR;GACD;AACD,UAAO;EACR,EACF;AACD,OAAK,WAAW,UAAU,KAAM;EAChC,MAAM,oBAAoB,KAAK,eAAe,YAC5C,KAAK,eAAe,cAAc,KAAK,eAAe;EACxD,MAAM,kBAAkB,CAAC,IAAI,IAAI,KAAK,QAAQ,QAAQ,OAAQ;AAC9D,MAAI,kBACF,OAAM,KAAK,QAAQ,QAAQ,aACzB,KAAK,QAAQ,KACb,aACA,QACA;GAAE;GAAmB;EAAiB,EACvC;AAEH,QAAM,KAAK,QAAQ,QAAQ,aACzB,KAAK,QAAQ,KACb,CAAC,GAAG,kBAAkB,GAAG,eAAgB,GACzC,QACA;GAAE;GAAmB;EAAiB,EACvC;AACD,MAAI,KAAK,eAAe,KACtB,OAAM,KAAK,QAAQ,QAAQ,aACzB,KAAK,QAAQ,KACb,KAAK,YAAY,OACjB,QACA;GAAE,mBAAmB;GAAM;GAAiB,QAAQ;EAAQ,EAC7D;AAEH,MAAI,KAAK,eAAe,KACtB,OAAM,KAAK,QAAQ,QAAQ,aACzB,KAAK,QAAQ,KACb,KAAK,YAAY,OACjB,QACA;GAAE,mBAAmB;GAAM;GAAiB,QAAQ;EAAQ,EAC7D;CAEJ;CAED,MAAM,SAAwB;EAC5B,MAAM,SAAS,KAAK,QAAQ,QAAQ,SAAS,KAAK,GAAG;AACrD,MACE,QAAQ,SAAS,aAChB,eAAe,KAAK,CAAC,QAAQ,OAAO,UAAU,IAAI,CAEnD;EAEF,MAAM,EAAE,IAAI,GAAG,OAAO;EACtB,MAAM,SAAS,MAAM,KAAK,QAAQ,IAAI,WAAW,cAAc,GAAW;AAC1E,MAAI,UAAU,KAAM;EACpB,MAAM,UAAU,MAAM,OAAO,UAAU,KAAK,QAAQ,QAAQ;AAC5D,MAAI,WAAW,KAAM;EACrB,MAAMC,oCAAiC,IAAI;AAC3C,aAAW,MAAM,OAAO,QAAQ,QAAQ,KAAK,QAAQ,QAAQ,CAC3D,KAAI,eAAe,WAAW,IAAI,QAAQ,KACxC,mBAAkB,IAAI,IAAI,KAAK,KAAK;EAGxC,MAAMF,WAAqC,CAAE;EAC7C,MAAM,iBAAiB,MAAM,KAAK,QAAQ,QAAQ,kBAChD,KAAK,QAAQ,IACd;AACD,OAAK,MAAM,OAAO,kBAChB,UAAS,KAAK,KAAK,QAAQ,QAAQ,aAAa,KAAK,EAAE,eAAgB,EAAC,CAAC;EAE3E,MAAM,kBAAkB,CAAC,MAAM,QAAQ,IAAI,SAAS,EAAE,OAAO,QAAQ;EACrE,MAAM,WAAW,IAAI,OAAO;GAC1B,IAAI,IAAI,IAAI,WAAW,KAAK;GAC5B,OAAO,KAAK,QAAQ,QAAQ,YAAY,KAAK,QAAQ,IAAI,WAAW;GACpE,KAAK,OAAO;GACZ,KAAK,OAAO;GACZ,QAAQ,IAAI,UAAU,EACpB,IAAI,KAAK,GACV;EACF;EACD,MAAM,kBAAkB,CAAC,IAAI,IAAI,KAAK,QAAQ,QAAQ,OAAQ;AAC9D,QAAM,KAAK,QAAQ,QAAQ,aACzB,KAAK,QAAQ,KACb,aACA,UACA;GAAE,mBAAmB;GAAM;EAAiB,EAC7C;AACD,MAAI,gBAAgB,SAAS,EAC3B,OAAM,KAAK,QAAQ,QAAQ,aACzB,KAAK,QAAQ,KACb,iBACA,UACA;GAAE,mBAAmB;GAAM;EAAiB,EAC7C;AAEH,MAAI,KAAK,eAAe,KACtB,OAAM,KAAK,QAAQ,QAAQ,aACzB,KAAK,QAAQ,KACb,KAAK,YAAY,OACjB,UACA;GAAE,mBAAmB;GAAM;GAAiB,QAAQ;EAAQ,EAC7D;AAEH,MAAI,KAAK,eAAe,KACtB,OAAM,KAAK,QAAQ,QAAQ,aACzB,KAAK,QAAQ,KACb,KAAK,YAAY,OACjB,UACA;GAAE,mBAAmB;GAAM;GAAiB,QAAQ;EAAQ,EAC7D;CAEJ;AACF;AAGD,MAAM,YAAY,IAAI,qBAAqB;AAE3C,MAAM,UAAU,IAAI,IAAI,UAAU,EAChC,WAAW;CACT,GAAG;CACH,GAAG;EAAC,GAAG,UAAU,KAAK,CAAE;EAAE;EAAS;CAAY;AAChD,EACF;AAED,MAAa,UAAU,IAAI,IAAI,UAAU;CACvC,WAAW,CAAE;CACb,gBAAgB;AACjB;AAkBD,eAAsB,cACpBG,KACAhB,SACAY,eACAK,aACAC,aACAC,aAAsB,OACa;AACnC,KAAI,IAAI,MAAM,KAAM,OAAM,IAAI,UAAU;UAC/B,IAAI,WAAW,KACtB,OAAM,IAAI,UAAU;CAEtB,MAAM,iBAAiB,MAAM,QAAQ,QAAQ,kBAAkB,QAAQ,IAAI;CAC3E,MAAM,UAAU;EACd,eAAe,QAAQ,QAAQ;EAC/B;EACA,eAAe;CAChB;CACD,MAAM,QAAQ,IAAI,eAAe,SAAS,QAAQ,SAAS,OACvD,MAAM,QAAQ,UAAU,GACxB,MAAM,IAAI,eAAe,QAAQ;AACrC,KAAI,SAAS,KACX,OAAM,IAAI,UAAU;CAEtB,MAAM,UAAU,IAAI,QAAQ,UAAU;CACtC,MAAM,OAAO,QAAQ,QAAQ,QAAQ;CACrC,MAAM,OAAO,QAAQ,QAAQ,QAAQ;CACrC,MAAMC,WAAoB,CAAE;CAC5B,MAAM,oCAAoB,IAAI;CAC9B,MAAMT,WAAsB,CAAE;CAC9B,MAAMU,aAAqB,CAAE;AAC7B,YAAW,MAAM,OAAO,IAAI,QAAQ,QAAQ,CAC1C,KAAI,eAAe,WAAW,IAAI,QAAQ,MAAM;EAC9C,MAAM,MAAM,IAAI,KAAK,SAAS,QAAQ,SAAS,OAC3C,MAAM,QAAQ,UAAU,GACxB,cAAc,IAAI,KAAK,SAAS,OAChC,MAAM,QAAQ,QAAQ,aAAa,IAAI,MAAM,QAAQ,GACrD,cAAc,IAAI,KAAK;AAC3B,MAAI,QAAQ,IAAI,CAAE,UAAS,KAAK,IAAI;AACpC,oBAAkB,IAAI,IAAI,KAAK,KAAK;CACrC,WAAU,eAAe,QACxB,UAAS,KAAK,IAAI;UACT,eAAe,QAAQ,YAAY,IAAI,CAChD,YAAW,KAAK,IAAI;CAGxB,MAAMC,cAA0B,CAAE;AAClC,YAAW,MAAM,cAAc,IAAI,eAAe,QAAQ,CACxD,KAAI,sBAAsB,SAAU,aAAY,KAAK,WAAW;AAElE,KAAI,eAAe,MAAM;EACvB,IAAIC;EACJ,MAAM,SAAS,QAAQ,QAAQ,SAAS,IAAI,cAAc;AAE1D,MAAI,QAAQ,SAAS,YAAY,eAAe,SAAS,OAAO,MAAM,EAAE;GAGtE,MAAMC,MAA8B,OAAO;AAC3C,QAAK,MAAM,QAAQ,IAAI,gBACrB,KACA,QAAQ,SACR,OAAO,OAAO,GACf;EACF,MACC,MAAK,MAAM,IAAI,eAAe,QAAQ;AAExC,MACE,cAAc,WAAW,cAAc,eACvC,cAAc,QAAQ,cAAc,SAEpC,eAAc,MAAM,cAAc,IAAI,SAAS,cAAc;CAEhE;AACD,KAAI,eAAe,MAAM;EACvB,IAAIC,WAAuB;AAC3B,OAAK,MAAM,aAAa,YAAY;AAClC,OAAI,UAAU,QAAQ,KAAM;AAC5B,cAAW,UAAU;AACrB;EACD;AACD,MAAI,YAAY,KAAM,YAAW,IAAI;EACrC,IAAIC,KAAoB;EACxB,MAAM,SAAS,QAAQ,QAAQ,SAAS,SAAS;AAEjD,MAAI,QAAQ,SAAS,YAAY,eAAe,SAAS,OAAO,MAAM,EAAE;GAGtE,MAAMF,MAA8B,OAAO;AAC3C,QAAK,MAAM,QAAQ,IAAI,gBACrB,KACA,QAAQ,SACR,OAAO,OAAO,GACf;EACF,WAAU,YAAY,KACrB,MAAK,MAAM,QAAQ,QAAQ,aAAa,UAAU,QAAQ;AAE5D,MACE,cAAc,WAAW,cAAc,eACvC,cAAc,QAAQ,cAAc,SAEpC,eAAc,MAAM,cAAc,IAAI,SAAS,cAAc;CAEhE;AACD,QAAO,KAAK,aAAa,wBAAwB,aAAa,SAAS;EACrE;EACA,IAAI,IAAI;EACR;EACA,YAAY,qBACV,IAAI,OACJ,IAAI,OACJ,OACA,kBACD;EACD,UAAU,IAAI,mBAAmB,iBAC7B,IAAI,QAAQ;EAEhB,MAAM,OAAO,KAAK;EAClB;EACA;EACA;EACA;EACA;EACA;EACA,WAAW,IAAI;EACf,SAAS,IAAI;CACd;AACF;AAED,SAAgB,qBACdG,OACAC,OACAC,OACAC,mBACmB;CACnB,MAAM,KAAK,MAAM,IAAI,CAAC,QAAQ,IAAI,KAAK;CACvC,MAAM,KAAK,MAAM,IAAI,CAAC,QAAQ,IAAI,KAAK;CACvC,MAAM,aAAa,IAAI,IAAI,CAAC,GAAG,IAAI,GAAG,EAAG;AACzC,QAAO,GAAG,SAAS,kBAAkB,KAAK,GACtC,WACA,GAAG,SAAS,kBAAkB,KAAK,GACnC,aACA,MAAM,eAAe,SAClB,GAAG,SAAS,MAAM,YAAY,KAAK,IAClC,GAAG,SAAS,MAAM,YAAY,KAAK,IACvC,cACA,WAAW,OAAO,KAChB,WAAW,aAAa,qCAAqB,IAAI,MAAM,CAAC,SACtD,WAAW,OACf,WACA;AACL;AAED,SAAgB,YAAYC,KAAoB;AAC9C,KAAI,IAAI,QAAQ,4CAA6C,QAAO;UAC3D,IAAI,aAAa,KAAM,QAAO;CAEvC,MAAM,SAAS,IAAI,UAAU,MAAM,IAAI;CACvC,MAAM,OAAO,OAAO,GAAG,MAAM;AAC7B,KAAI,SAAS,4BAA6B,QAAO;CACjD,MAAMC,SAAiC,CAAE;AACzC,MAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;EACtC,MAAM,QAAQ,OAAO,GAAG,MAAM,CAAC,MAAM,IAAI;AACzC,MAAI,MAAM,WAAW,EACnB,QAAO,MAAM,MAAM,MAAM,GAAG,QAAQ,MAAM,GAAG;CAEhD;AACD,QAAO,SAAS,yBACd,OAAO,YAAY;AACtB"}
|
package/dist/pages.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Temporal, toTemporalInstant } from "@js-temporal/polyfill";
|
|
|
2
2
|
Date.prototype.toTemporalInstant = toTemporalInstant;
|
|
3
3
|
import { BotImpl } from "./bot-impl.js";
|
|
4
4
|
import { Hono } from "hono";
|
|
5
|
-
import * as
|
|
5
|
+
import * as hono_types1 from "hono/types";
|
|
6
6
|
|
|
7
7
|
//#region src/pages.d.ts
|
|
8
8
|
interface Bindings {
|
|
@@ -12,7 +12,7 @@ interface Bindings {
|
|
|
12
12
|
interface Env {
|
|
13
13
|
readonly Bindings: Bindings;
|
|
14
14
|
}
|
|
15
|
-
declare const app: Hono<Env,
|
|
15
|
+
declare const app: Hono<Env, hono_types1.BlankSchema, "/">;
|
|
16
16
|
//# sourceMappingURL=pages.d.ts.map
|
|
17
17
|
|
|
18
18
|
//#endregion
|
package/dist/session-impl.js
CHANGED
|
@@ -206,7 +206,7 @@ var SessionImpl = class {
|
|
|
206
206
|
continue;
|
|
207
207
|
}
|
|
208
208
|
if (object == null || !isMessageObject(object)) continue;
|
|
209
|
-
const message = await createMessage(object, this, {});
|
|
209
|
+
const message = await createMessage(object, this, {}, void 0, void 0, true);
|
|
210
210
|
yield message;
|
|
211
211
|
}
|
|
212
212
|
}
|
package/dist/session-impl.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-impl.js","names":["bot: BotImpl<TContextData>","context: Context<TContextData>","actor: Actor | URL | string","actorId: URL","content: Text<\"block\", TContextData>","options:\n | SessionImplPublishOptions<TContextData>\n | SessionImplPublishOptionsWithClass<MessageClass, TContextData>\n | SessionImplPublishOptionsWithQuestion<TContextData>","Note","mentionedActorIds: URL[]","Mention","inclusiveOptions: Note[]","exclusiveOptions: Note[]","voters: number | null","endTime: Temporal.Instant | null","PUBLIC_COLLECTION","Create","cachedObjects: Record<string, Object>","promises: Promise<Object | null>[]","isActor","options: SessionGetOutboxOptions","object: Object | null"],"sources":["../src/session-impl.ts"],"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/>.\nimport {\n type Actor,\n type Context,\n Create,\n isActor,\n LanguageString,\n Mention,\n Note,\n type Object,\n PUBLIC_COLLECTION,\n} from \"@fedify/fedify\";\nimport { Collection, Follow, Link, Undo } from \"@fedify/fedify/vocab\";\nimport { getLogger } from \"@logtape/logtape\";\nimport { encode } from \"html-entities\";\nimport { v7 as uuidv7 } from \"uuid\";\nimport type { BotImpl } from \"./bot-impl.ts\";\nimport { createMessage, isMessageObject } from \"./message-impl.ts\";\nimport {\n type AuthorizedMessage,\n type Message,\n type MessageClass,\n Question,\n} from \"./message.ts\";\nimport type { Uuid } from \"./repository.ts\";\nimport type {\n Session,\n SessionGetOutboxOptions,\n SessionPublishOptions,\n SessionPublishOptionsWithClass,\n SessionPublishOptionsWithQuestion,\n} from \"./session.ts\";\nimport type { Text } from \"./text.ts\";\n\nconst logger = getLogger([\"botkit\", \"session\"]);\n\nexport interface SessionImplPublishOptions<TContextData>\n extends SessionPublishOptions<TContextData> {\n replyTarget?: Message<MessageClass, TContextData>;\n}\n\nexport interface SessionImplPublishOptionsWithClass<\n T extends MessageClass,\n TContextData,\n> extends\n SessionPublishOptionsWithClass<T, TContextData>,\n SessionImplPublishOptions<TContextData> {\n}\n\nexport interface SessionImplPublishOptionsWithQuestion<TContextData>\n extends\n SessionPublishOptionsWithQuestion<TContextData>,\n SessionImplPublishOptionsWithClass<Question, TContextData> {\n}\n\nexport class SessionImpl<TContextData> implements Session<TContextData> {\n readonly bot: BotImpl<TContextData>;\n readonly context: Context<TContextData>;\n\n constructor(bot: BotImpl<TContextData>, context: Context<TContextData>) {\n this.bot = bot;\n this.context = context;\n }\n\n get actorId() {\n return this.context.getActorUri(this.bot.identifier);\n }\n\n get actorHandle() {\n return `@${this.bot.username}@${this.context.host}` as const;\n }\n\n async getActor(): Promise<Actor> {\n return (await this.bot.dispatchActor(this.context, this.bot.identifier))!;\n }\n\n async follow(actor: Actor | URL | string): Promise<void> {\n if (actor instanceof URL || typeof actor === \"string\") {\n if (\n actor instanceof URL && actor.href === this.actorId.href ||\n typeof actor === \"string\" &&\n (actor === this.actorId.href || actor === this.actorHandle)\n ) {\n throw new TypeError(\"The bot cannot follow itself.\");\n }\n const documentLoader = await this.context.getDocumentLoader(this.bot);\n const object = await this.context.lookupObject(actor, { documentLoader });\n if (!isActor(object)) {\n throw new TypeError(\"The resolved object is not an Actor.\");\n }\n actor = object;\n }\n if (actor.id == null) {\n throw new TypeError(\"The actor does not have an ID.\");\n } else if (actor.id.href === this.actorId.href) {\n throw new TypeError(\"The bot cannot follow itself.\");\n }\n const followee = await this.bot.repository.getFollowee(actor.id);\n if (followee != null) {\n logger.warn(\n \"The bot is already following the actor {actor}.\",\n { actor: actor.id.href },\n );\n return;\n }\n const id = uuidv7() as Uuid;\n const follow = new Follow({\n id: this.context.getObjectUri(Follow, { id }),\n actor: this.context.getActorUri(this.bot.identifier),\n object: actor.id,\n to: actor.id,\n });\n await this.bot.repository.addSentFollow(id, follow);\n await this.context.sendActivity(\n this.bot,\n actor,\n follow,\n { excludeBaseUris: [new URL(this.context.origin)] },\n );\n }\n\n async unfollow(actor: Actor | URL | string): Promise<void> {\n const documentLoader = await this.context.getDocumentLoader(this.bot);\n if (actor instanceof URL || typeof actor === \"string\") {\n if (\n actor instanceof URL && actor.href === this.actorId.href ||\n typeof actor === \"string\" &&\n (actor === this.actorId.href || actor === this.actorHandle)\n ) {\n throw new TypeError(\"The bot cannot unfollow itself.\");\n }\n const object = await this.context.lookupObject(actor, { documentLoader });\n if (!isActor(object)) {\n throw new TypeError(\"The resolved object is not an Actor.\");\n }\n actor = object;\n }\n if (actor.id == null) {\n throw new TypeError(\"The actor does not have an ID.\");\n } else if (actor.id.href === this.actorId.href) {\n throw new TypeError(\"The bot cannot unfollow itself.\");\n }\n const follow = await this.bot.repository.getFollowee(actor.id);\n if (follow == null) {\n logger.warn(\n \"The bot is not following the actor {actor}.\",\n { actor: actor.id.href },\n );\n return;\n }\n await this.bot.repository.removeFollowee(actor.id);\n if (follow.id != null && follow.objectId?.href === actor.id.href) {\n await this.context.sendActivity(\n this.bot,\n actor,\n new Undo({\n id: new URL(\"#undo\", follow.id),\n actor: this.context.getActorUri(this.bot.identifier),\n object: follow,\n to: actor.id,\n }),\n { excludeBaseUris: [new URL(this.context.origin)] },\n );\n }\n }\n\n async follows(actor: Actor | URL | string): Promise<boolean> {\n let actorId: URL;\n if (isActor(actor)) {\n if (actor.id == null) {\n throw new TypeError(\"The actor does not have an ID.\");\n }\n actorId = actor.id;\n } else if (actor instanceof URL) {\n actorId = actor;\n } else {\n if (actor.startsWith(\"http://\") || actor.startsWith(\"https://\")) {\n actorId = new URL(actor);\n } else {\n if (actor === this.actorHandle) return false;\n const documentLoader = await this.context.getDocumentLoader(this.bot);\n const object = await this.context.lookupObject(actor, {\n documentLoader,\n });\n if (!isActor(object)) {\n throw new TypeError(\"The resolved object is not an Actor.\");\n }\n if (object.id == null) {\n throw new TypeError(\"The actor does not have an ID.\");\n }\n actorId = object.id;\n }\n }\n if (actorId.href === this.actorId.href) return false;\n const follow = await this.bot.repository.getFollowee(actorId);\n return follow != null;\n }\n\n async publish(\n content: Text<\"block\", TContextData>,\n options?: SessionImplPublishOptions<TContextData>,\n ): Promise<AuthorizedMessage<Note, TContextData>>;\n async publish<T extends MessageClass>(\n content: Text<\"block\", TContextData>,\n options: SessionImplPublishOptionsWithClass<T, TContextData>,\n ): Promise<AuthorizedMessage<T, TContextData>>;\n async publish(\n content: Text<\"block\", TContextData>,\n options: SessionImplPublishOptionsWithQuestion<TContextData>,\n ): Promise<AuthorizedMessage<Question, TContextData>>;\n async publish(\n content: Text<\"block\", TContextData>,\n options:\n | SessionImplPublishOptions<TContextData>\n | SessionImplPublishOptionsWithClass<MessageClass, TContextData>\n | SessionImplPublishOptionsWithQuestion<TContextData> = {},\n ): Promise<AuthorizedMessage<MessageClass, TContextData>> {\n const published = new Date();\n const id = uuidv7({ msecs: +published }) as Uuid;\n const cls = \"class\" in options ? options.class : Note;\n const visibility = options.visibility ?? \"public\";\n let contentHtml = \"\";\n for await (const chunk of content.getHtml(this)) {\n contentHtml += chunk;\n }\n const tags = await Array.fromAsync(content.getTags(this));\n const mentionedActorIds: URL[] = [];\n for (const tag of tags) {\n if (tag instanceof Mention && tag.href != null) {\n mentionedActorIds.push(tag.href);\n }\n }\n if (options.quoteTarget != null) {\n let url = options.quoteTarget.raw.url ?? options.quoteTarget.id;\n if (url instanceof Link) url = url.href ?? options.quoteTarget.id;\n contentHtml += `\\n\\n<p class=\"quote-inline\"><br>RE: <a href=\"${\n encode(url.href)\n }\">${encode(url.href)}</a></p>`;\n tags.push(\n new Link({\n mediaType:\n 'application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"',\n rel: \"https://misskey-hub.net/ns#_misskey_quote\",\n href: options.quoteTarget.id,\n name: `RE: ${url.href}`,\n }),\n );\n }\n let inclusiveOptions: Note[] = [];\n let exclusiveOptions: Note[] = [];\n let voters: number | null = null;\n let endTime: Temporal.Instant | null = null;\n if (\"class\" in options && options.class === Question && \"poll\" in options) {\n if (options.poll.options.length < 2) {\n throw new TypeError(\"At least two options are required in a poll.\");\n } else if (\n new Set(options.poll.options).size != options.poll.options.length\n ) {\n throw new TypeError(\"Duplicate options are not allowed in a poll.\");\n } else if (options.poll.options.some((o) => o.trim() === \"\")) {\n throw new TypeError(\"Poll options cannot be empty.\");\n }\n const pollOptions = options.poll.options.map((option) =>\n new Note({\n name: option,\n replies: new Collection({ totalItems: 0 }),\n })\n );\n if (options.poll.multiple) inclusiveOptions = pollOptions;\n else exclusiveOptions = pollOptions;\n voters = 0;\n endTime = options.poll.endTime;\n }\n const msg = new cls({\n id: this.context.getObjectUri<MessageClass>(cls, { id }),\n contents: options.language == null\n ? [contentHtml]\n : [new LanguageString(contentHtml, options.language), contentHtml],\n replyTarget: options.replyTarget?.id,\n quoteUrl: options.quoteTarget?.id,\n tags,\n attribution: this.context.getActorUri(this.bot.identifier),\n attachments: options.attachments ?? [],\n inclusiveOptions,\n exclusiveOptions,\n voters,\n endTime,\n tos: visibility === \"public\"\n ? [PUBLIC_COLLECTION, ...mentionedActorIds]\n : visibility === \"unlisted\" || visibility === \"followers\"\n ? [\n this.context.getFollowersUri(this.bot.identifier),\n ...mentionedActorIds,\n ]\n : mentionedActorIds,\n ccs: visibility === \"public\"\n ? [this.context.getFollowersUri(this.bot.identifier)]\n : visibility === \"unlisted\"\n ? [PUBLIC_COLLECTION]\n : [],\n published: published.toTemporalInstant(),\n url: new URL(`/message/${id}`, this.context.origin),\n });\n const activity = new Create({\n id: this.context.getObjectUri(Create, { id }),\n actors: msg.attributionIds,\n tos: msg.toIds,\n ccs: msg.ccIds,\n object: msg,\n published: published.toTemporalInstant(),\n });\n await this.bot.repository.addMessage(id, activity);\n const preferSharedInbox = visibility === \"public\" ||\n visibility === \"unlisted\" || visibility === \"followers\";\n const excludeBaseUris = [new URL(this.context.origin)];\n if (preferSharedInbox) {\n await this.context.sendActivity(\n this.bot,\n \"followers\",\n activity,\n { preferSharedInbox, excludeBaseUris },\n );\n }\n const cachedObjects: Record<string, Object> = {};\n for (const cachedObject of content.getCachedObjects()) {\n if (cachedObject.id == null) continue;\n cachedObjects[cachedObject.id.href] = cachedObject;\n }\n if (mentionedActorIds.length > 0) {\n const documentLoader = await this.context.getDocumentLoader(this.bot);\n const promises: Promise<Object | null>[] = [];\n for (const mentionedActorId of mentionedActorIds) {\n const cachedObject = cachedObjects[mentionedActorId.href];\n const promise = cachedObject == null\n ? this.context.lookupObject(\n mentionedActorId,\n { documentLoader },\n )\n : Promise.resolve(cachedObject);\n promises.push(promise);\n }\n const objects = await Promise.all(promises);\n const mentionedActors = objects.filter(isActor);\n await this.context.sendActivity(\n this.bot,\n mentionedActors,\n activity,\n { preferSharedInbox, excludeBaseUris },\n );\n }\n if (options.replyTarget != null) {\n await this.context.sendActivity(\n this.bot,\n options.replyTarget.actor,\n activity,\n { preferSharedInbox, excludeBaseUris, fanout: \"skip\" },\n );\n }\n if (options.quoteTarget != null) {\n await this.context.sendActivity(\n this.bot,\n options.quoteTarget.actor,\n activity,\n { preferSharedInbox, excludeBaseUris, fanout: \"skip\" },\n );\n }\n return await createMessage(\n msg,\n this,\n cachedObjects,\n options.replyTarget,\n options.quoteTarget,\n true,\n );\n }\n\n async *getOutbox(\n options: SessionGetOutboxOptions = {},\n ): AsyncIterable<AuthorizedMessage<MessageClass, TContextData>> {\n for await (const activity of this.bot.repository.getMessages(options)) {\n let object: Object | null;\n try {\n object = await activity.getObject(this.context);\n } catch {\n continue;\n }\n if (object == null || !isMessageObject(object)) continue;\n const message = await createMessage(object, this, {});\n yield message;\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"session-impl.js","names":["bot: BotImpl<TContextData>","context: Context<TContextData>","actor: Actor | URL | string","actorId: URL","content: Text<\"block\", TContextData>","options:\n | SessionImplPublishOptions<TContextData>\n | SessionImplPublishOptionsWithClass<MessageClass, TContextData>\n | SessionImplPublishOptionsWithQuestion<TContextData>","Note","mentionedActorIds: URL[]","Mention","inclusiveOptions: Note[]","exclusiveOptions: Note[]","voters: number | null","endTime: Temporal.Instant | null","PUBLIC_COLLECTION","Create","cachedObjects: Record<string, Object>","promises: Promise<Object | null>[]","isActor","options: SessionGetOutboxOptions","object: Object | null"],"sources":["../src/session-impl.ts"],"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/>.\nimport {\n type Actor,\n type Context,\n Create,\n isActor,\n LanguageString,\n Mention,\n Note,\n type Object,\n PUBLIC_COLLECTION,\n} from \"@fedify/fedify\";\nimport { Collection, Follow, Link, Undo } from \"@fedify/fedify/vocab\";\nimport { getLogger } from \"@logtape/logtape\";\nimport { encode } from \"html-entities\";\nimport { v7 as uuidv7 } from \"uuid\";\nimport type { BotImpl } from \"./bot-impl.ts\";\nimport { createMessage, isMessageObject } from \"./message-impl.ts\";\nimport {\n type AuthorizedMessage,\n type Message,\n type MessageClass,\n Question,\n} from \"./message.ts\";\nimport type { Uuid } from \"./repository.ts\";\nimport type {\n Session,\n SessionGetOutboxOptions,\n SessionPublishOptions,\n SessionPublishOptionsWithClass,\n SessionPublishOptionsWithQuestion,\n} from \"./session.ts\";\nimport type { Text } from \"./text.ts\";\n\nconst logger = getLogger([\"botkit\", \"session\"]);\n\nexport interface SessionImplPublishOptions<TContextData>\n extends SessionPublishOptions<TContextData> {\n replyTarget?: Message<MessageClass, TContextData>;\n}\n\nexport interface SessionImplPublishOptionsWithClass<\n T extends MessageClass,\n TContextData,\n> extends\n SessionPublishOptionsWithClass<T, TContextData>,\n SessionImplPublishOptions<TContextData> {\n}\n\nexport interface SessionImplPublishOptionsWithQuestion<TContextData>\n extends\n SessionPublishOptionsWithQuestion<TContextData>,\n SessionImplPublishOptionsWithClass<Question, TContextData> {\n}\n\nexport class SessionImpl<TContextData> implements Session<TContextData> {\n readonly bot: BotImpl<TContextData>;\n readonly context: Context<TContextData>;\n\n constructor(bot: BotImpl<TContextData>, context: Context<TContextData>) {\n this.bot = bot;\n this.context = context;\n }\n\n get actorId() {\n return this.context.getActorUri(this.bot.identifier);\n }\n\n get actorHandle() {\n return `@${this.bot.username}@${this.context.host}` as const;\n }\n\n async getActor(): Promise<Actor> {\n return (await this.bot.dispatchActor(this.context, this.bot.identifier))!;\n }\n\n async follow(actor: Actor | URL | string): Promise<void> {\n if (actor instanceof URL || typeof actor === \"string\") {\n if (\n actor instanceof URL && actor.href === this.actorId.href ||\n typeof actor === \"string\" &&\n (actor === this.actorId.href || actor === this.actorHandle)\n ) {\n throw new TypeError(\"The bot cannot follow itself.\");\n }\n const documentLoader = await this.context.getDocumentLoader(this.bot);\n const object = await this.context.lookupObject(actor, { documentLoader });\n if (!isActor(object)) {\n throw new TypeError(\"The resolved object is not an Actor.\");\n }\n actor = object;\n }\n if (actor.id == null) {\n throw new TypeError(\"The actor does not have an ID.\");\n } else if (actor.id.href === this.actorId.href) {\n throw new TypeError(\"The bot cannot follow itself.\");\n }\n const followee = await this.bot.repository.getFollowee(actor.id);\n if (followee != null) {\n logger.warn(\n \"The bot is already following the actor {actor}.\",\n { actor: actor.id.href },\n );\n return;\n }\n const id = uuidv7() as Uuid;\n const follow = new Follow({\n id: this.context.getObjectUri(Follow, { id }),\n actor: this.context.getActorUri(this.bot.identifier),\n object: actor.id,\n to: actor.id,\n });\n await this.bot.repository.addSentFollow(id, follow);\n await this.context.sendActivity(\n this.bot,\n actor,\n follow,\n { excludeBaseUris: [new URL(this.context.origin)] },\n );\n }\n\n async unfollow(actor: Actor | URL | string): Promise<void> {\n const documentLoader = await this.context.getDocumentLoader(this.bot);\n if (actor instanceof URL || typeof actor === \"string\") {\n if (\n actor instanceof URL && actor.href === this.actorId.href ||\n typeof actor === \"string\" &&\n (actor === this.actorId.href || actor === this.actorHandle)\n ) {\n throw new TypeError(\"The bot cannot unfollow itself.\");\n }\n const object = await this.context.lookupObject(actor, { documentLoader });\n if (!isActor(object)) {\n throw new TypeError(\"The resolved object is not an Actor.\");\n }\n actor = object;\n }\n if (actor.id == null) {\n throw new TypeError(\"The actor does not have an ID.\");\n } else if (actor.id.href === this.actorId.href) {\n throw new TypeError(\"The bot cannot unfollow itself.\");\n }\n const follow = await this.bot.repository.getFollowee(actor.id);\n if (follow == null) {\n logger.warn(\n \"The bot is not following the actor {actor}.\",\n { actor: actor.id.href },\n );\n return;\n }\n await this.bot.repository.removeFollowee(actor.id);\n if (follow.id != null && follow.objectId?.href === actor.id.href) {\n await this.context.sendActivity(\n this.bot,\n actor,\n new Undo({\n id: new URL(\"#undo\", follow.id),\n actor: this.context.getActorUri(this.bot.identifier),\n object: follow,\n to: actor.id,\n }),\n { excludeBaseUris: [new URL(this.context.origin)] },\n );\n }\n }\n\n async follows(actor: Actor | URL | string): Promise<boolean> {\n let actorId: URL;\n if (isActor(actor)) {\n if (actor.id == null) {\n throw new TypeError(\"The actor does not have an ID.\");\n }\n actorId = actor.id;\n } else if (actor instanceof URL) {\n actorId = actor;\n } else {\n if (actor.startsWith(\"http://\") || actor.startsWith(\"https://\")) {\n actorId = new URL(actor);\n } else {\n if (actor === this.actorHandle) return false;\n const documentLoader = await this.context.getDocumentLoader(this.bot);\n const object = await this.context.lookupObject(actor, {\n documentLoader,\n });\n if (!isActor(object)) {\n throw new TypeError(\"The resolved object is not an Actor.\");\n }\n if (object.id == null) {\n throw new TypeError(\"The actor does not have an ID.\");\n }\n actorId = object.id;\n }\n }\n if (actorId.href === this.actorId.href) return false;\n const follow = await this.bot.repository.getFollowee(actorId);\n return follow != null;\n }\n\n async publish(\n content: Text<\"block\", TContextData>,\n options?: SessionImplPublishOptions<TContextData>,\n ): Promise<AuthorizedMessage<Note, TContextData>>;\n async publish<T extends MessageClass>(\n content: Text<\"block\", TContextData>,\n options: SessionImplPublishOptionsWithClass<T, TContextData>,\n ): Promise<AuthorizedMessage<T, TContextData>>;\n async publish(\n content: Text<\"block\", TContextData>,\n options: SessionImplPublishOptionsWithQuestion<TContextData>,\n ): Promise<AuthorizedMessage<Question, TContextData>>;\n async publish(\n content: Text<\"block\", TContextData>,\n options:\n | SessionImplPublishOptions<TContextData>\n | SessionImplPublishOptionsWithClass<MessageClass, TContextData>\n | SessionImplPublishOptionsWithQuestion<TContextData> = {},\n ): Promise<AuthorizedMessage<MessageClass, TContextData>> {\n const published = new Date();\n const id = uuidv7({ msecs: +published }) as Uuid;\n const cls = \"class\" in options ? options.class : Note;\n const visibility = options.visibility ?? \"public\";\n let contentHtml = \"\";\n for await (const chunk of content.getHtml(this)) {\n contentHtml += chunk;\n }\n const tags = await Array.fromAsync(content.getTags(this));\n const mentionedActorIds: URL[] = [];\n for (const tag of tags) {\n if (tag instanceof Mention && tag.href != null) {\n mentionedActorIds.push(tag.href);\n }\n }\n if (options.quoteTarget != null) {\n let url = options.quoteTarget.raw.url ?? options.quoteTarget.id;\n if (url instanceof Link) url = url.href ?? options.quoteTarget.id;\n contentHtml += `\\n\\n<p class=\"quote-inline\"><br>RE: <a href=\"${\n encode(url.href)\n }\">${encode(url.href)}</a></p>`;\n tags.push(\n new Link({\n mediaType:\n 'application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"',\n rel: \"https://misskey-hub.net/ns#_misskey_quote\",\n href: options.quoteTarget.id,\n name: `RE: ${url.href}`,\n }),\n );\n }\n let inclusiveOptions: Note[] = [];\n let exclusiveOptions: Note[] = [];\n let voters: number | null = null;\n let endTime: Temporal.Instant | null = null;\n if (\"class\" in options && options.class === Question && \"poll\" in options) {\n if (options.poll.options.length < 2) {\n throw new TypeError(\"At least two options are required in a poll.\");\n } else if (\n new Set(options.poll.options).size != options.poll.options.length\n ) {\n throw new TypeError(\"Duplicate options are not allowed in a poll.\");\n } else if (options.poll.options.some((o) => o.trim() === \"\")) {\n throw new TypeError(\"Poll options cannot be empty.\");\n }\n const pollOptions = options.poll.options.map((option) =>\n new Note({\n name: option,\n replies: new Collection({ totalItems: 0 }),\n })\n );\n if (options.poll.multiple) inclusiveOptions = pollOptions;\n else exclusiveOptions = pollOptions;\n voters = 0;\n endTime = options.poll.endTime;\n }\n const msg = new cls({\n id: this.context.getObjectUri<MessageClass>(cls, { id }),\n contents: options.language == null\n ? [contentHtml]\n : [new LanguageString(contentHtml, options.language), contentHtml],\n replyTarget: options.replyTarget?.id,\n quoteUrl: options.quoteTarget?.id,\n tags,\n attribution: this.context.getActorUri(this.bot.identifier),\n attachments: options.attachments ?? [],\n inclusiveOptions,\n exclusiveOptions,\n voters,\n endTime,\n tos: visibility === \"public\"\n ? [PUBLIC_COLLECTION, ...mentionedActorIds]\n : visibility === \"unlisted\" || visibility === \"followers\"\n ? [\n this.context.getFollowersUri(this.bot.identifier),\n ...mentionedActorIds,\n ]\n : mentionedActorIds,\n ccs: visibility === \"public\"\n ? [this.context.getFollowersUri(this.bot.identifier)]\n : visibility === \"unlisted\"\n ? [PUBLIC_COLLECTION]\n : [],\n published: published.toTemporalInstant(),\n url: new URL(`/message/${id}`, this.context.origin),\n });\n const activity = new Create({\n id: this.context.getObjectUri(Create, { id }),\n actors: msg.attributionIds,\n tos: msg.toIds,\n ccs: msg.ccIds,\n object: msg,\n published: published.toTemporalInstant(),\n });\n await this.bot.repository.addMessage(id, activity);\n const preferSharedInbox = visibility === \"public\" ||\n visibility === \"unlisted\" || visibility === \"followers\";\n const excludeBaseUris = [new URL(this.context.origin)];\n if (preferSharedInbox) {\n await this.context.sendActivity(\n this.bot,\n \"followers\",\n activity,\n { preferSharedInbox, excludeBaseUris },\n );\n }\n const cachedObjects: Record<string, Object> = {};\n for (const cachedObject of content.getCachedObjects()) {\n if (cachedObject.id == null) continue;\n cachedObjects[cachedObject.id.href] = cachedObject;\n }\n if (mentionedActorIds.length > 0) {\n const documentLoader = await this.context.getDocumentLoader(this.bot);\n const promises: Promise<Object | null>[] = [];\n for (const mentionedActorId of mentionedActorIds) {\n const cachedObject = cachedObjects[mentionedActorId.href];\n const promise = cachedObject == null\n ? this.context.lookupObject(\n mentionedActorId,\n { documentLoader },\n )\n : Promise.resolve(cachedObject);\n promises.push(promise);\n }\n const objects = await Promise.all(promises);\n const mentionedActors = objects.filter(isActor);\n await this.context.sendActivity(\n this.bot,\n mentionedActors,\n activity,\n { preferSharedInbox, excludeBaseUris },\n );\n }\n if (options.replyTarget != null) {\n await this.context.sendActivity(\n this.bot,\n options.replyTarget.actor,\n activity,\n { preferSharedInbox, excludeBaseUris, fanout: \"skip\" },\n );\n }\n if (options.quoteTarget != null) {\n await this.context.sendActivity(\n this.bot,\n options.quoteTarget.actor,\n activity,\n { preferSharedInbox, excludeBaseUris, fanout: \"skip\" },\n );\n }\n return await createMessage(\n msg,\n this,\n cachedObjects,\n options.replyTarget,\n options.quoteTarget,\n true,\n );\n }\n\n async *getOutbox(\n options: SessionGetOutboxOptions = {},\n ): AsyncIterable<AuthorizedMessage<MessageClass, TContextData>> {\n for await (const activity of this.bot.repository.getMessages(options)) {\n let object: Object | null;\n try {\n object = await activity.getObject(this.context);\n } catch {\n continue;\n }\n if (object == null || !isMessageObject(object)) continue;\n const message = await createMessage(\n object,\n this,\n {},\n undefined,\n undefined,\n true,\n );\n yield message;\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-impl.test.d.ts","names":[],"sources":["../src/session-impl.test.ts"],"sourcesContent":[],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"session-impl.test.d.ts","names":[],"sources":["../src/session-impl.test.ts"],"sourcesContent":[],"mappings":";;;;;;;UAm3BiB,YAAA;4BACW;YAChB;;UAGK,WAAA,SAAoB;kBACnB;AANlB;AAA6B,iBASb,iBAAA,CATa,GAAA,EAUtB,OAVsB,CAAA,IAAA,CAAA,EAAA,MAAA,EAWnB,GAXmB,GAAA,MAAA,CAAA,EAY1B,WAZ0B"}
|
|
@@ -604,6 +604,15 @@ test("SessionImpl.getOutbox()", async (t) => {
|
|
|
604
604
|
const messageIds = messages.map((msg) => msg.id.href);
|
|
605
605
|
assert.deepStrictEqual(messageIds, ["https://example.com/ap/note/0194244f-d800-7873-8993-ef71ccd47306", "https://example.com/ap/note/01941f29-7c00-7fe8-ab0a-7b593990a3c0"]);
|
|
606
606
|
});
|
|
607
|
+
await t.test("messages should have update and delete methods", async () => {
|
|
608
|
+
const outbox = session.getOutbox({ order: "oldest" });
|
|
609
|
+
const messages = await Array.fromAsync(outbox);
|
|
610
|
+
assert.strictEqual(messages.length, 4);
|
|
611
|
+
for (const message of messages) {
|
|
612
|
+
assert.strictEqual(typeof message.update, "function");
|
|
613
|
+
assert.strictEqual(typeof message.delete, "function");
|
|
614
|
+
}
|
|
615
|
+
});
|
|
607
616
|
});
|
|
608
617
|
function createMockContext(bot, origin) {
|
|
609
618
|
const ctx = bot.federation.createContext(new URL(origin), void 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-impl.test.js","names":["bot: BotImpl<void>","origin: URL | string"],"sources":["../src/session-impl.test.ts"],"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/>.\nimport { type Context, MemoryKvStore } from \"@fedify/fedify/federation\";\nimport {\n type Activity,\n Create,\n Follow,\n Note,\n Person,\n PUBLIC_COLLECTION,\n Question,\n type Recipient,\n Undo,\n} from \"@fedify/fedify/vocab\";\nimport assert from \"node:assert\";\nimport { describe, test } from \"node:test\";\nimport { BotImpl } from \"./bot-impl.ts\";\nimport { createMessage } from \"./message-impl.ts\";\nimport { MemoryRepository, type Uuid } from \"./repository.ts\";\nimport { SessionImpl } from \"./session-impl.ts\";\nimport { mention, text } from \"./text.ts\";\n\ntest(\"SessionImpl.follow()\", async (t) => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = createMockContext(bot, \"https://example.com\");\n const session = new SessionImpl(bot, ctx);\n\n await t.test(\"follow\", async () => {\n const actor = new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n });\n await session.follow(actor);\n assert.deepStrictEqual(ctx.sentActivities.length, 1);\n const { recipients, activity } = ctx.sentActivities[0];\n assert.deepStrictEqual(recipients, [actor]);\n assert.ok(activity instanceof Follow);\n const parsed = ctx.parseUri(activity.id);\n assert.deepStrictEqual(parsed?.type, \"object\");\n assert.ok(parsed?.type === \"object\");\n assert.deepStrictEqual(parsed.class, Follow);\n assert.deepStrictEqual(activity.actorId, ctx.getActorUri(bot.identifier));\n assert.deepStrictEqual(activity.objectId, actor.id);\n assert.deepStrictEqual(activity.toIds, [actor.id]);\n const follow = await repository.getSentFollow(parsed.values.id as Uuid);\n assert.ok(follow != null);\n assert.deepStrictEqual(\n await follow.toJsonLd({ format: \"compact\" }),\n await activity.toJsonLd({ format: \"compact\" }),\n );\n });\n\n await t.test(\"follow again\", async () => {\n ctx.sentActivities = [];\n await repository.addFollowee(\n new URL(\"https://example.com/ap/actor/alice\"),\n new Follow({\n id: new URL(\n \"https://example.com/ap/follow/4114eadb-2596-408f-ad99-06f467c9ace0\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new URL(\"https://example.com/ap/actor/alice\"),\n }),\n );\n const actor = new Person({\n id: new URL(\"https://example.com/ap/actor/alice\"),\n preferredUsername: \"alice\",\n });\n await session.follow(actor);\n assert.deepStrictEqual(ctx.sentActivities, []);\n });\n\n await t.test(\"follow bot itself\", async () => {\n ctx.sentActivities = [];\n await assert.rejects(\n () => session.follow(session.actorId.href),\n TypeError,\n \"The bot cannot follow itself.\",\n );\n assert.deepStrictEqual(ctx.sentActivities, []);\n\n await assert.rejects(\n () => session.follow(session.actorId),\n TypeError,\n \"The bot cannot follow itself.\",\n );\n assert.deepStrictEqual(ctx.sentActivities, []);\n\n await assert.rejects(\n () => session.follow(session.actorHandle),\n TypeError,\n \"The bot cannot follow itself.\",\n );\n assert.deepStrictEqual(ctx.sentActivities, []);\n\n const actor = await session.getActor();\n await assert.rejects(\n () => session.follow(actor),\n TypeError,\n \"The bot cannot follow itself.\",\n );\n assert.deepStrictEqual(ctx.sentActivities, []);\n });\n});\n\ntest(\"SessionImpl.unfollow()\", async (t) => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = createMockContext(bot, \"https://example.com\");\n const session = new SessionImpl(bot, ctx);\n\n await t.test(\"unfollow\", async () => {\n await repository.addFollowee(\n new URL(\"https://example.com/ap/actor/alice\"),\n new Follow({\n id: new URL(\n \"https://example.com/ap/follow/4114eadb-2596-408f-ad99-06f467c9ace0\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new URL(\"https://example.com/ap/actor/alice\"),\n }),\n );\n const actor = new Person({\n id: new URL(\"https://example.com/ap/actor/alice\"),\n preferredUsername: \"alice\",\n });\n await session.unfollow(actor);\n assert.deepStrictEqual(ctx.sentActivities.length, 1);\n const { recipients, activity } = ctx.sentActivities[0];\n assert.deepStrictEqual(recipients, [actor]);\n assert.ok(activity instanceof Undo);\n const object = await activity.getObject(ctx);\n assert.ok(object instanceof Follow);\n assert.deepStrictEqual(\n object.id,\n new URL(\n \"https://example.com/ap/follow/4114eadb-2596-408f-ad99-06f467c9ace0\",\n ),\n );\n assert.deepStrictEqual(object.actorId, ctx.getActorUri(bot.identifier));\n assert.deepStrictEqual(\n await repository.getFollowee(\n new URL(\"https://example.com/ap/actor/alice\"),\n ),\n undefined,\n );\n });\n\n await t.test(\"unfollow again\", async () => {\n ctx.sentActivities = [];\n const actor = new Person({\n id: new URL(\"https://example.com/ap/actor/alice\"),\n preferredUsername: \"alice\",\n });\n await session.unfollow(actor);\n assert.deepStrictEqual(ctx.sentActivities, []);\n });\n\n await t.test(\"unfollow bot itself\", async () => {\n ctx.sentActivities = [];\n await assert.rejects(\n () => session.unfollow(session.actorId.href),\n TypeError,\n \"The bot cannot unfollow itself.\",\n );\n assert.deepStrictEqual(ctx.sentActivities, []);\n\n await assert.rejects(\n () => session.unfollow(session.actorId),\n TypeError,\n \"The bot cannot unfollow itself.\",\n );\n assert.deepStrictEqual(ctx.sentActivities, []);\n\n await assert.rejects(\n () => session.unfollow(session.actorHandle),\n TypeError,\n \"The bot cannot unfollow itself.\",\n );\n assert.deepStrictEqual(ctx.sentActivities, []);\n\n const actor = await session.getActor();\n await assert.rejects(\n () => session.unfollow(actor),\n TypeError,\n \"The bot cannot unfollow itself.\",\n );\n assert.deepStrictEqual(ctx.sentActivities, []);\n });\n});\n\ndescribe(\"SessionImpl.follows()\", () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = createMockContext(bot, \"https://example.com\");\n const session = new SessionImpl(bot, ctx);\n\n test(\"when it follows\", async () => {\n const followeeId = new URL(\"https://example.com/ap/actor/alice\");\n const followee = new Person({\n id: followeeId,\n preferredUsername: \"alice\",\n });\n await repository.addFollowee(\n new URL(\"https://example.com/ap/actor/alice\"),\n new Follow({\n id: new URL(\n \"https://example.com/ap/follow/4114eadb-2596-408f-ad99-06f467c9ace0\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: followee,\n }),\n );\n assert.ok(await session.follows(followeeId.href));\n assert.ok(await session.follows(followeeId));\n assert.ok(await session.follows(followee));\n });\n\n test(\"when it does not follow\", async () => {\n const actorId = new URL(\"https://example.com/ap/actor/john\");\n const actor = new Person({\n id: actorId,\n preferredUsername: \"john\",\n });\n assert.deepStrictEqual(await session.follows(actorId.href), false);\n assert.deepStrictEqual(await session.follows(actorId), false);\n assert.deepStrictEqual(await session.follows(actor), false);\n });\n\n test(\"bot itself\", async () => {\n assert.deepStrictEqual(await session.follows(session.actorId.href), false);\n assert.deepStrictEqual(await session.follows(session.actorId), false);\n assert.deepStrictEqual(\n await session.follows(await session.getActor()),\n false,\n );\n assert.deepStrictEqual(await session.follows(session.actorHandle), false);\n });\n});\n\ntest(\"SessionImpl.publish()\", async (t) => {\n const kv = new MemoryKvStore();\n const bot = new BotImpl<void>({ kv, username: \"bot\" });\n const ctx = createMockContext(bot, \"https://example.com\");\n const session = new SessionImpl(bot, ctx);\n\n await t.test(\"public\", async () => {\n ctx.sentActivities = [];\n const publicMsg = await session.publish(text`Hello, world!`);\n assert.deepStrictEqual(ctx.sentActivities.length, 1);\n const { recipients, activity } = ctx.sentActivities[0];\n assert.deepStrictEqual(recipients, \"followers\");\n assert.ok(activity instanceof Create);\n assert.deepStrictEqual(activity.actorId, ctx.getActorUri(bot.identifier));\n assert.deepStrictEqual(activity.toIds, [PUBLIC_COLLECTION]);\n assert.deepStrictEqual(activity.ccIds, [\n ctx.getFollowersUri(bot.identifier),\n ]);\n const object = await activity.getObject(ctx);\n assert.ok(object instanceof Note);\n assert.deepStrictEqual(\n object.attributionId,\n ctx.getActorUri(bot.identifier),\n );\n assert.deepStrictEqual(object.toIds, [PUBLIC_COLLECTION]);\n assert.deepStrictEqual(object.ccIds, [ctx.getFollowersUri(bot.identifier)]);\n assert.deepStrictEqual(object.content, \"<p>Hello, world!</p>\");\n assert.deepStrictEqual(object.tagIds, []);\n assert.deepStrictEqual(publicMsg.id, object.id);\n assert.deepStrictEqual(publicMsg.text, \"Hello, world!\");\n assert.deepStrictEqual(publicMsg.html, \"<p>Hello, world!</p>\");\n assert.deepStrictEqual(publicMsg.visibility, \"public\");\n assert.deepStrictEqual(publicMsg.mentions, []);\n });\n\n await t.test(\"unlisted\", async () => {\n ctx.sentActivities = [];\n const unlistedMsg = await session.publish(text`Hello!`, {\n visibility: \"unlisted\",\n });\n assert.deepStrictEqual(ctx.sentActivities.length, 1);\n const { recipients, activity } = ctx.sentActivities[0];\n assert.deepStrictEqual(recipients, \"followers\");\n assert.ok(activity instanceof Create);\n assert.deepStrictEqual(activity.actorId, ctx.getActorUri(bot.identifier));\n assert.deepStrictEqual(activity.toIds, [\n ctx.getFollowersUri(bot.identifier),\n ]);\n assert.deepStrictEqual(activity.ccIds, [PUBLIC_COLLECTION]);\n const object = await activity.getObject(ctx);\n assert.ok(object instanceof Note);\n assert.deepStrictEqual(\n object.attributionId,\n ctx.getActorUri(bot.identifier),\n );\n assert.deepStrictEqual(object.toIds, [ctx.getFollowersUri(bot.identifier)]);\n assert.deepStrictEqual(object.ccIds, [PUBLIC_COLLECTION]);\n assert.deepStrictEqual(object.content, \"<p>Hello!</p>\");\n assert.deepStrictEqual(object.tagIds, []);\n assert.deepStrictEqual(unlistedMsg.id, object.id);\n assert.deepStrictEqual(unlistedMsg.text, \"Hello!\");\n assert.deepStrictEqual(unlistedMsg.html, \"<p>Hello!</p>\");\n assert.deepStrictEqual(unlistedMsg.visibility, \"unlisted\");\n assert.deepStrictEqual(unlistedMsg.mentions, []);\n });\n\n await t.test(\"followers\", async () => {\n ctx.sentActivities = [];\n const followersMsg = await session.publish(text`Hi!`, {\n visibility: \"followers\",\n });\n assert.deepStrictEqual(ctx.sentActivities.length, 1);\n const { recipients, activity } = ctx.sentActivities[0];\n assert.deepStrictEqual(recipients, \"followers\");\n assert.ok(activity instanceof Create);\n assert.deepStrictEqual(activity.actorId, ctx.getActorUri(bot.identifier));\n assert.deepStrictEqual(activity.toIds, [\n ctx.getFollowersUri(bot.identifier),\n ]);\n assert.deepStrictEqual(activity.ccIds, []);\n const object = await activity.getObject(ctx);\n assert.ok(object instanceof Note);\n assert.deepStrictEqual(\n object.attributionId,\n ctx.getActorUri(bot.identifier),\n );\n assert.deepStrictEqual(object.toIds, [ctx.getFollowersUri(bot.identifier)]);\n assert.deepStrictEqual(object.ccIds, []);\n assert.deepStrictEqual(object.content, \"<p>Hi!</p>\");\n assert.deepStrictEqual(object.tagIds, []);\n assert.deepStrictEqual(followersMsg.id, object.id);\n assert.deepStrictEqual(followersMsg.text, \"Hi!\");\n assert.deepStrictEqual(followersMsg.html, \"<p>Hi!</p>\");\n assert.deepStrictEqual(followersMsg.visibility, \"followers\");\n assert.deepStrictEqual(followersMsg.mentions, []);\n });\n\n await t.test(\"direct\", async () => {\n const mentioned = new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n });\n ctx.sentActivities = [];\n const directMsg = await session.publish(\n text`Hey ${mention(mentioned)}!`,\n { visibility: \"direct\" },\n );\n assert.deepStrictEqual(ctx.sentActivities.length, 1);\n const { recipients, activity } = ctx.sentActivities[0];\n assert.deepStrictEqual(recipients, [mentioned]);\n assert.ok(activity instanceof Create);\n assert.deepStrictEqual(activity.actorId, ctx.getActorUri(bot.identifier));\n assert.deepStrictEqual(activity.toIds, [mentioned.id]);\n assert.deepStrictEqual(activity.ccIds, []);\n const object = await activity.getObject(ctx);\n assert.ok(object instanceof Note);\n assert.deepStrictEqual(\n object.attributionId,\n ctx.getActorUri(bot.identifier),\n );\n assert.deepStrictEqual(object.toIds, [mentioned.id]);\n assert.deepStrictEqual(object.ccIds, []);\n assert.deepStrictEqual(\n object.content,\n '<p>Hey <a href=\"https://example.com/ap/actor/john\" translate=\"no\" ' +\n 'class=\"h-card u-url mention\" target=\"_blank\">@<span>john@example.com' +\n \"</span></a>!</p>\",\n );\n const tags = await Array.fromAsync(object.getTags());\n assert.deepStrictEqual(tags.length, 1);\n assert.deepStrictEqual(directMsg.id, object.id);\n assert.deepStrictEqual(directMsg.text, \"Hey @john@example.com!\");\n assert.deepStrictEqual(directMsg.html, object.content);\n assert.deepStrictEqual(directMsg.visibility, \"direct\");\n // assert.deepStrictEqual(directMsg.mentions, [mentioned]); // FIXME\n });\n\n await t.test(\"quote\", async () => {\n const originalAuthor = new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n });\n const originalPost = new Note({\n id: new URL(\n \"https://example.com/ap/note/c1c792ce-a0be-4685-b396-e59e5ef8c788\",\n ),\n content: \"<p>Hello, world!</p>\",\n attribution: originalAuthor,\n to: new URL(\"https://example.com/ap/actor/john/followers\"),\n cc: PUBLIC_COLLECTION,\n });\n const originalMsg = await createMessage<Note, void>(\n originalPost,\n session,\n {},\n );\n ctx.sentActivities = [];\n const quote = await session.publish(text`Check this out!`, {\n quoteTarget: originalMsg,\n });\n assert.deepStrictEqual(ctx.sentActivities.length, 2);\n const { recipients, activity } = ctx.sentActivities[0];\n assert.deepStrictEqual(recipients, \"followers\");\n assert.ok(activity instanceof Create);\n assert.deepStrictEqual(activity.actorId, ctx.getActorUri(bot.identifier));\n assert.deepStrictEqual(activity.toIds, [PUBLIC_COLLECTION]);\n assert.deepStrictEqual(activity.ccIds, [\n ctx.getFollowersUri(bot.identifier),\n ]);\n const object = await activity.getObject(ctx);\n const { recipients: recipients2, activity: activity2 } =\n ctx.sentActivities[1];\n assert.deepStrictEqual(recipients2, [originalAuthor]);\n assert.ok(activity2 instanceof Create);\n assert.deepStrictEqual(activity2.actorId, ctx.getActorUri(bot.identifier));\n assert.deepStrictEqual(activity2.toIds, [PUBLIC_COLLECTION]);\n assert.deepStrictEqual(activity2.ccIds, [\n ctx.getFollowersUri(bot.identifier),\n ]);\n assert.ok(object instanceof Note);\n assert.deepStrictEqual(\n object.attributionId,\n ctx.getActorUri(bot.identifier),\n );\n assert.deepStrictEqual(object.toIds, [PUBLIC_COLLECTION]);\n assert.deepStrictEqual(object.ccIds, [ctx.getFollowersUri(bot.identifier)]);\n assert.deepStrictEqual(\n object.content,\n `<p>Check this out!</p>\n\n<p class=\"quote-inline\"><br>RE: <a href=\"${originalMsg.id.href}\">${originalMsg.id.href}</a></p>`,\n );\n assert.deepStrictEqual(object.quoteUrl, originalMsg.id);\n assert.deepStrictEqual(quote.id, object.id);\n assert.deepStrictEqual(\n quote.text,\n `Check this out!\\n\\nRE: ${originalMsg.id.href}`,\n );\n assert.deepStrictEqual(\n quote.html,\n `<p>Check this out!</p>\n\n<p><br>RE: <a href=\"${originalMsg.id.href}\">${originalMsg.id.href}</a></p>`,\n );\n assert.deepStrictEqual(quote.visibility, \"public\");\n assert.deepStrictEqual(quote.quoteTarget?.id, originalMsg.id);\n });\n\n await t.test(\"poll single choice\", async () => {\n ctx.sentActivities = [];\n const endTime = Temporal.Now.instant().add({ hours: 24 });\n const poll = await session.publish(text`What's your favorite color?`, {\n class: Question,\n poll: {\n multiple: false,\n options: [\"Red\", \"Blue\", \"Green\"],\n endTime,\n },\n });\n assert.deepStrictEqual(ctx.sentActivities.length, 1);\n const { recipients, activity } = ctx.sentActivities[0];\n assert.deepStrictEqual(recipients, \"followers\");\n assert.ok(activity instanceof Create);\n assert.deepStrictEqual(activity.actorId, ctx.getActorUri(bot.identifier));\n assert.deepStrictEqual(activity.toIds, [PUBLIC_COLLECTION]);\n assert.deepStrictEqual(activity.ccIds, [\n ctx.getFollowersUri(bot.identifier),\n ]);\n const object = await activity.getObject(ctx);\n assert.ok(object instanceof Question);\n assert.deepStrictEqual(\n object.attributionId,\n ctx.getActorUri(bot.identifier),\n );\n assert.deepStrictEqual(object.toIds, [PUBLIC_COLLECTION]);\n assert.deepStrictEqual(object.ccIds, [ctx.getFollowersUri(bot.identifier)]);\n assert.deepStrictEqual(\n object.content,\n \"<p>What's your favorite color?</p>\",\n );\n assert.deepStrictEqual(object.endTime, endTime);\n assert.deepStrictEqual(object.voters, 0);\n assert.deepStrictEqual(object.inclusiveOptionIds, []);\n\n const exclusiveOptions = await Array.fromAsync(\n object.getExclusiveOptions(ctx),\n );\n assert.deepStrictEqual(exclusiveOptions.length, 3);\n assert.ok(exclusiveOptions[0] instanceof Note);\n assert.deepStrictEqual(exclusiveOptions[0].name?.toString(), \"Red\");\n assert.ok(exclusiveOptions[1] instanceof Note);\n assert.deepStrictEqual(exclusiveOptions[1].name?.toString(), \"Blue\");\n assert.ok(exclusiveOptions[2] instanceof Note);\n assert.deepStrictEqual(exclusiveOptions[2].name?.toString(), \"Green\");\n\n for (const option of exclusiveOptions) {\n const replies = await option.getReplies(ctx);\n assert.deepStrictEqual(replies?.totalItems, 0);\n }\n\n assert.deepStrictEqual(poll.id, object.id);\n assert.deepStrictEqual(poll.text, \"What's your favorite color?\");\n assert.deepStrictEqual(\n poll.html,\n \"<p>What's your favorite color?</p>\",\n );\n assert.deepStrictEqual(poll.visibility, \"public\");\n });\n\n await t.test(\"poll multiple choice\", async () => {\n ctx.sentActivities = [];\n const endTime = Temporal.Now.instant().add({ hours: 24 * 7 });\n const poll = await session.publish(\n text`Which programming languages do you know?`,\n {\n class: Question,\n poll: {\n multiple: true,\n options: [\"JavaScript\", \"TypeScript\", \"Python\", \"Rust\"],\n endTime,\n },\n visibility: \"unlisted\",\n },\n );\n assert.deepStrictEqual(ctx.sentActivities.length, 1);\n const { recipients, activity } = ctx.sentActivities[0];\n assert.deepStrictEqual(recipients, \"followers\");\n assert.ok(activity instanceof Create);\n const object = await activity.getObject(ctx);\n assert.ok(object instanceof Question);\n assert.deepStrictEqual(object.endTime, endTime);\n assert.deepStrictEqual(object.voters, 0);\n assert.deepStrictEqual(object.exclusiveOptionIds, []);\n\n const inclusiveOptions = await Array.fromAsync(\n object.getInclusiveOptions(ctx),\n );\n assert.deepStrictEqual(inclusiveOptions.length, 4);\n assert.ok(inclusiveOptions[0] instanceof Note);\n assert.deepStrictEqual(inclusiveOptions[0].name?.toString(), \"JavaScript\");\n assert.ok(inclusiveOptions[1] instanceof Note);\n assert.deepStrictEqual(inclusiveOptions[1].name?.toString(), \"TypeScript\");\n assert.ok(inclusiveOptions[2] instanceof Note);\n assert.deepStrictEqual(inclusiveOptions[2].name?.toString(), \"Python\");\n assert.ok(inclusiveOptions[3] instanceof Note);\n assert.deepStrictEqual(inclusiveOptions[3].name?.toString(), \"Rust\");\n\n assert.deepStrictEqual(poll.visibility, \"unlisted\");\n assert.deepStrictEqual(activity.toIds, [\n ctx.getFollowersUri(bot.identifier),\n ]);\n assert.deepStrictEqual(activity.ccIds, [PUBLIC_COLLECTION]);\n });\n\n await t.test(\"poll with direct visibility\", async () => {\n const mentioned = new Person({\n id: new URL(\"https://example.com/ap/actor/alice\"),\n preferredUsername: \"alice\",\n });\n ctx.sentActivities = [];\n const endTime = Temporal.Now.instant().add({ hours: 12 });\n const poll = await session.publish(\n text`Hey ${mention(mentioned)}, what do you think?`,\n {\n class: Question,\n poll: {\n multiple: false,\n options: [\"Good\", \"Bad\", \"Neutral\"],\n endTime,\n },\n visibility: \"direct\",\n },\n );\n assert.deepStrictEqual(ctx.sentActivities.length, 1);\n const { recipients, activity } = ctx.sentActivities[0];\n assert.deepStrictEqual(recipients, [mentioned]);\n assert.ok(activity instanceof Create);\n const object = await activity.getObject(ctx);\n assert.ok(object instanceof Question);\n assert.deepStrictEqual(object.toIds, [mentioned.id]);\n assert.deepStrictEqual(object.ccIds, []);\n assert.deepStrictEqual(poll.visibility, \"direct\");\n });\n\n await t.test(\"poll end-to-end workflow\", async () => {\n // Create fresh repository and session for isolation\n const freshRepository = new MemoryRepository();\n const freshBot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository: freshRepository,\n username: \"testbot\",\n });\n const freshCtx = createMockContext(freshBot, \"https://example.com\");\n const freshSession = new SessionImpl(freshBot, freshCtx);\n\n const endTime = Temporal.Now.instant().add({ hours: 1 });\n\n // 1. Create a poll\n const poll = await freshSession.publish(\n text`What should we have for lunch?`,\n {\n class: Question,\n poll: {\n multiple: false,\n options: [\"Pizza\", \"Burgers\", \"Salad\"],\n endTime,\n },\n },\n );\n\n // Verify poll was created correctly\n assert.deepStrictEqual(freshCtx.sentActivities.length, 1);\n const { activity: createActivity } = freshCtx.sentActivities[0];\n assert.ok(createActivity instanceof Create);\n const pollObject = await createActivity.getObject(freshCtx);\n assert.ok(pollObject instanceof Question);\n assert.deepStrictEqual(pollObject.endTime, endTime);\n\n // Get poll options\n const options = await Array.fromAsync(\n pollObject.getExclusiveOptions(freshCtx),\n );\n assert.deepStrictEqual(options.length, 3);\n assert.deepStrictEqual(options[0].name?.toString(), \"Pizza\");\n assert.deepStrictEqual(options[1].name?.toString(), \"Burgers\");\n assert.deepStrictEqual(options[2].name?.toString(), \"Salad\");\n\n // 2. Verify poll is accessible via getOutbox\n const outbox = freshSession.getOutbox({ order: \"newest\" });\n const messages = await Array.fromAsync(outbox);\n assert.deepStrictEqual(messages.length, 1);\n assert.deepStrictEqual(messages[0].id, poll.id);\n assert.deepStrictEqual(messages[0].text, \"What should we have for lunch?\");\n\n // 3. Verify poll structure\n assert.deepStrictEqual(poll.visibility, \"public\");\n assert.deepStrictEqual(poll.mentions, []);\n });\n});\n\ntest(\"SessionImpl.getOutbox()\", async (t) => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = createMockContext(bot, \"https://example.com\");\n const session = new SessionImpl(bot, ctx);\n\n const messageA = new Create({\n id: new URL(\n \"https://example.com/ap/create/01941f29-7c00-7fe8-ab0a-7b593990a3c0\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/01941f29-7c00-7fe8-ab0a-7b593990a3c0\",\n ),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n content: \"Hello, world!\",\n published: Temporal.Instant.from(\"2025-01-01T00:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-01T00:00:00Z\"),\n });\n const messageB = new Create({\n id: new URL(\n \"https://example.com/ap/create/0194244f-d800-7873-8993-ef71ccd47306\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/0194244f-d800-7873-8993-ef71ccd47306\",\n ),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n content: \"Hello, world!\",\n published: Temporal.Instant.from(\"2025-01-02T00:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-02T00:00:00Z\"),\n });\n const messageC = new Create({\n id: new URL(\n \"https://example.com/ap/create/01942976-3400-7f34-872e-2cbf0f9eeac4\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/01942976-3400-7f34-872e-2cbf0f9eeac4\",\n ),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n content: \"Hello, world!\",\n published: Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n });\n const messageD = new Create({\n id: new URL(\n \"https://example.com/ap/create/01942e9c-9000-7480-a553-7a6ce737ce14\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/01942e9c-9000-7480-a553-7a6ce737ce14\",\n ),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n content: \"Hello, world!\",\n published: Temporal.Instant.from(\"2025-01-04T00:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-04T00:00:00Z\"),\n });\n await repository.addMessage(\"01941f29-7c00-7fe8-ab0a-7b593990a3c0\", messageA);\n await repository.addMessage(\"0194244f-d800-7873-8993-ef71ccd47306\", messageB);\n await repository.addMessage(\"01942976-3400-7f34-872e-2cbf0f9eeac4\", messageC);\n await repository.addMessage(\"01942e9c-9000-7480-a553-7a6ce737ce14\", messageD);\n\n await t.test(\"default\", async () => {\n const outbox = session.getOutbox({ order: \"oldest\" });\n const messages = await Array.fromAsync(outbox);\n assert.deepStrictEqual(messages.length, 4);\n\n assert.deepStrictEqual(\n messages[0].id.href,\n \"https://example.com/ap/note/01941f29-7c00-7fe8-ab0a-7b593990a3c0\",\n );\n assert.deepStrictEqual(\n messages[0].actor.id?.href,\n \"https://example.com/ap/actor/bot\",\n );\n assert.deepStrictEqual(messages[0].visibility, \"unlisted\");\n assert.deepStrictEqual(messages[0].text, \"Hello, world!\");\n assert.deepStrictEqual(\n messages[0].published,\n Temporal.Instant.from(\"2025-01-01T00:00:00Z\"),\n );\n\n assert.deepStrictEqual(\n messages[1].id.href,\n \"https://example.com/ap/note/0194244f-d800-7873-8993-ef71ccd47306\",\n );\n assert.deepStrictEqual(\n messages[1].actor.id?.href,\n \"https://example.com/ap/actor/bot\",\n );\n assert.deepStrictEqual(messages[1].visibility, \"unlisted\");\n assert.deepStrictEqual(messages[1].text, \"Hello, world!\");\n assert.deepStrictEqual(\n messages[1].published,\n Temporal.Instant.from(\"2025-01-02T00:00:00Z\"),\n );\n\n assert.deepStrictEqual(\n messages[2].id.href,\n \"https://example.com/ap/note/01942976-3400-7f34-872e-2cbf0f9eeac4\",\n );\n assert.deepStrictEqual(\n messages[2].actor.id?.href,\n \"https://example.com/ap/actor/bot\",\n );\n assert.deepStrictEqual(messages[2].visibility, \"unlisted\");\n assert.deepStrictEqual(messages[2].text, \"Hello, world!\");\n assert.deepStrictEqual(\n messages[2].published,\n Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n );\n\n assert.deepStrictEqual(\n messages[3].id.href,\n \"https://example.com/ap/note/01942e9c-9000-7480-a553-7a6ce737ce14\",\n );\n assert.deepStrictEqual(\n messages[3].actor.id?.href,\n \"https://example.com/ap/actor/bot\",\n );\n assert.deepStrictEqual(messages[3].visibility, \"unlisted\");\n assert.deepStrictEqual(messages[3].text, \"Hello, world!\");\n assert.deepStrictEqual(\n messages[3].published,\n Temporal.Instant.from(\"2025-01-04T00:00:00Z\"),\n );\n });\n\n await t.test(\"order: 'oldest'\", async () => {\n const outbox = session.getOutbox({ order: \"oldest\" });\n const messages = await Array.fromAsync(outbox);\n const messageIds = messages.map((msg) => msg.id.href);\n assert.deepStrictEqual(messageIds, [\n \"https://example.com/ap/note/01941f29-7c00-7fe8-ab0a-7b593990a3c0\",\n \"https://example.com/ap/note/0194244f-d800-7873-8993-ef71ccd47306\",\n \"https://example.com/ap/note/01942976-3400-7f34-872e-2cbf0f9eeac4\",\n \"https://example.com/ap/note/01942e9c-9000-7480-a553-7a6ce737ce14\",\n ]);\n });\n\n await t.test(\"order: 'newest'\", async () => {\n const outbox = session.getOutbox({ order: \"newest\" });\n const messages = await Array.fromAsync(outbox);\n const messageIds = messages.map((msg) => msg.id.href);\n assert.deepStrictEqual(messageIds, [\n \"https://example.com/ap/note/01942e9c-9000-7480-a553-7a6ce737ce14\",\n \"https://example.com/ap/note/01942976-3400-7f34-872e-2cbf0f9eeac4\",\n \"https://example.com/ap/note/0194244f-d800-7873-8993-ef71ccd47306\",\n \"https://example.com/ap/note/01941f29-7c00-7fe8-ab0a-7b593990a3c0\",\n ]);\n });\n\n await t.test(\"since\", async () => {\n const outbox = session.getOutbox({\n since: Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n });\n const messages = await Array.fromAsync(outbox);\n const messageIds = messages.map((msg) => msg.id.href);\n assert.deepStrictEqual(messageIds, [\n \"https://example.com/ap/note/01942e9c-9000-7480-a553-7a6ce737ce14\",\n \"https://example.com/ap/note/01942976-3400-7f34-872e-2cbf0f9eeac4\",\n ]);\n });\n\n await t.test(\"until\", async () => {\n const outbox = session.getOutbox({\n until: Temporal.Instant.from(\"2025-01-02T00:00:00Z\"),\n });\n const messages = await Array.fromAsync(outbox);\n const messageIds = messages.map((msg) => msg.id.href);\n assert.deepStrictEqual(messageIds, [\n \"https://example.com/ap/note/0194244f-d800-7873-8993-ef71ccd47306\",\n \"https://example.com/ap/note/01941f29-7c00-7fe8-ab0a-7b593990a3c0\",\n ]);\n });\n});\n\nexport interface SentActivity {\n recipients: \"followers\" | Recipient[];\n activity: Activity;\n}\n\nexport interface MockContext extends Context<void> {\n sentActivities: SentActivity[];\n}\n\nexport function createMockContext(\n bot: BotImpl<void>,\n origin: URL | string,\n): MockContext {\n const ctx = bot.federation.createContext(\n new URL(origin),\n undefined,\n ) as MockContext;\n ctx.sentActivities = [];\n ctx.sendActivity = (_, recipients, activity) => {\n ctx.sentActivities.push({\n recipients: recipients === \"followers\"\n ? \"followers\"\n : Array.isArray(recipients)\n ? recipients\n : [recipients],\n activity,\n });\n return Promise.resolve();\n };\n return ctx;\n}\n"],"mappings":";;;;;;;;;;;;;;;AAmCA,KAAK,wBAAwB,OAAO,MAAM;CACxC,MAAM,aAAa,IAAI;CACvB,MAAM,MAAM,IAAI,QAAc;EAC5B,IAAI,IAAI;EACR;EACA,UAAU;CACX;CACD,MAAM,MAAM,kBAAkB,KAAK,sBAAsB;CACzD,MAAM,UAAU,IAAI,YAAY,KAAK;AAErC,OAAM,EAAE,KAAK,UAAU,YAAY;EACjC,MAAM,QAAQ,IAAI,OAAO;GACvB,IAAI,IAAI,IAAI;GACZ,mBAAmB;EACpB;AACD,QAAM,QAAQ,OAAO,MAAM;AAC3B,SAAO,gBAAgB,IAAI,eAAe,QAAQ,EAAE;EACpD,MAAM,EAAE,YAAY,UAAU,GAAG,IAAI,eAAe;AACpD,SAAO,gBAAgB,YAAY,CAAC,KAAM,EAAC;AAC3C,SAAO,GAAG,oBAAoB,OAAO;EACrC,MAAM,SAAS,IAAI,SAAS,SAAS,GAAG;AACxC,SAAO,gBAAgB,QAAQ,MAAM,SAAS;AAC9C,SAAO,GAAG,QAAQ,SAAS,SAAS;AACpC,SAAO,gBAAgB,OAAO,OAAO,OAAO;AAC5C,SAAO,gBAAgB,SAAS,SAAS,IAAI,YAAY,IAAI,WAAW,CAAC;AACzE,SAAO,gBAAgB,SAAS,UAAU,MAAM,GAAG;AACnD,SAAO,gBAAgB,SAAS,OAAO,CAAC,MAAM,EAAG,EAAC;EAClD,MAAM,SAAS,MAAM,WAAW,cAAc,OAAO,OAAO,GAAW;AACvE,SAAO,GAAG,UAAU,KAAK;AACzB,SAAO,gBACL,MAAM,OAAO,SAAS,EAAE,QAAQ,UAAW,EAAC,EAC5C,MAAM,SAAS,SAAS,EAAE,QAAQ,UAAW,EAAC,CAC/C;CACF,EAAC;AAEF,OAAM,EAAE,KAAK,gBAAgB,YAAY;AACvC,MAAI,iBAAiB,CAAE;AACvB,QAAM,WAAW,YACf,IAAI,IAAI,uCACR,IAAI,OAAO;GACT,IAAI,IAAI,IACN;GAEF,OAAO,IAAI,IAAI;GACf,QAAQ,IAAI,IAAI;EACjB,GACF;EACD,MAAM,QAAQ,IAAI,OAAO;GACvB,IAAI,IAAI,IAAI;GACZ,mBAAmB;EACpB;AACD,QAAM,QAAQ,OAAO,MAAM;AAC3B,SAAO,gBAAgB,IAAI,gBAAgB,CAAE,EAAC;CAC/C,EAAC;AAEF,OAAM,EAAE,KAAK,qBAAqB,YAAY;AAC5C,MAAI,iBAAiB,CAAE;AACvB,QAAM,OAAO,QACX,MAAM,QAAQ,OAAO,QAAQ,QAAQ,KAAK,EAC1C,WACA,gCACD;AACD,SAAO,gBAAgB,IAAI,gBAAgB,CAAE,EAAC;AAE9C,QAAM,OAAO,QACX,MAAM,QAAQ,OAAO,QAAQ,QAAQ,EACrC,WACA,gCACD;AACD,SAAO,gBAAgB,IAAI,gBAAgB,CAAE,EAAC;AAE9C,QAAM,OAAO,QACX,MAAM,QAAQ,OAAO,QAAQ,YAAY,EACzC,WACA,gCACD;AACD,SAAO,gBAAgB,IAAI,gBAAgB,CAAE,EAAC;EAE9C,MAAM,QAAQ,MAAM,QAAQ,UAAU;AACtC,QAAM,OAAO,QACX,MAAM,QAAQ,OAAO,MAAM,EAC3B,WACA,gCACD;AACD,SAAO,gBAAgB,IAAI,gBAAgB,CAAE,EAAC;CAC/C,EAAC;AACH,EAAC;AAEF,KAAK,0BAA0B,OAAO,MAAM;CAC1C,MAAM,aAAa,IAAI;CACvB,MAAM,MAAM,IAAI,QAAc;EAC5B,IAAI,IAAI;EACR;EACA,UAAU;CACX;CACD,MAAM,MAAM,kBAAkB,KAAK,sBAAsB;CACzD,MAAM,UAAU,IAAI,YAAY,KAAK;AAErC,OAAM,EAAE,KAAK,YAAY,YAAY;AACnC,QAAM,WAAW,YACf,IAAI,IAAI,uCACR,IAAI,OAAO;GACT,IAAI,IAAI,IACN;GAEF,OAAO,IAAI,IAAI;GACf,QAAQ,IAAI,IAAI;EACjB,GACF;EACD,MAAM,QAAQ,IAAI,OAAO;GACvB,IAAI,IAAI,IAAI;GACZ,mBAAmB;EACpB;AACD,QAAM,QAAQ,SAAS,MAAM;AAC7B,SAAO,gBAAgB,IAAI,eAAe,QAAQ,EAAE;EACpD,MAAM,EAAE,YAAY,UAAU,GAAG,IAAI,eAAe;AACpD,SAAO,gBAAgB,YAAY,CAAC,KAAM,EAAC;AAC3C,SAAO,GAAG,oBAAoB,KAAK;EACnC,MAAM,SAAS,MAAM,SAAS,UAAU,IAAI;AAC5C,SAAO,GAAG,kBAAkB,OAAO;AACnC,SAAO,gBACL,OAAO,IACP,IAAI,IACF,sEAEH;AACD,SAAO,gBAAgB,OAAO,SAAS,IAAI,YAAY,IAAI,WAAW,CAAC;AACvE,SAAO,gBACL,MAAM,WAAW,YACf,IAAI,IAAI,sCACT,SAEF;CACF,EAAC;AAEF,OAAM,EAAE,KAAK,kBAAkB,YAAY;AACzC,MAAI,iBAAiB,CAAE;EACvB,MAAM,QAAQ,IAAI,OAAO;GACvB,IAAI,IAAI,IAAI;GACZ,mBAAmB;EACpB;AACD,QAAM,QAAQ,SAAS,MAAM;AAC7B,SAAO,gBAAgB,IAAI,gBAAgB,CAAE,EAAC;CAC/C,EAAC;AAEF,OAAM,EAAE,KAAK,uBAAuB,YAAY;AAC9C,MAAI,iBAAiB,CAAE;AACvB,QAAM,OAAO,QACX,MAAM,QAAQ,SAAS,QAAQ,QAAQ,KAAK,EAC5C,WACA,kCACD;AACD,SAAO,gBAAgB,IAAI,gBAAgB,CAAE,EAAC;AAE9C,QAAM,OAAO,QACX,MAAM,QAAQ,SAAS,QAAQ,QAAQ,EACvC,WACA,kCACD;AACD,SAAO,gBAAgB,IAAI,gBAAgB,CAAE,EAAC;AAE9C,QAAM,OAAO,QACX,MAAM,QAAQ,SAAS,QAAQ,YAAY,EAC3C,WACA,kCACD;AACD,SAAO,gBAAgB,IAAI,gBAAgB,CAAE,EAAC;EAE9C,MAAM,QAAQ,MAAM,QAAQ,UAAU;AACtC,QAAM,OAAO,QACX,MAAM,QAAQ,SAAS,MAAM,EAC7B,WACA,kCACD;AACD,SAAO,gBAAgB,IAAI,gBAAgB,CAAE,EAAC;CAC/C,EAAC;AACH,EAAC;AAEF,SAAS,yBAAyB,MAAM;CACtC,MAAM,aAAa,IAAI;CACvB,MAAM,MAAM,IAAI,QAAc;EAC5B,IAAI,IAAI;EACR;EACA,UAAU;CACX;CACD,MAAM,MAAM,kBAAkB,KAAK,sBAAsB;CACzD,MAAM,UAAU,IAAI,YAAY,KAAK;AAErC,MAAK,mBAAmB,YAAY;EAClC,MAAM,aAAa,IAAI,IAAI;EAC3B,MAAM,WAAW,IAAI,OAAO;GAC1B,IAAI;GACJ,mBAAmB;EACpB;AACD,QAAM,WAAW,YACf,IAAI,IAAI,uCACR,IAAI,OAAO;GACT,IAAI,IAAI,IACN;GAEF,OAAO,IAAI,IAAI;GACf,QAAQ;EACT,GACF;AACD,SAAO,GAAG,MAAM,QAAQ,QAAQ,WAAW,KAAK,CAAC;AACjD,SAAO,GAAG,MAAM,QAAQ,QAAQ,WAAW,CAAC;AAC5C,SAAO,GAAG,MAAM,QAAQ,QAAQ,SAAS,CAAC;CAC3C,EAAC;AAEF,MAAK,2BAA2B,YAAY;EAC1C,MAAM,UAAU,IAAI,IAAI;EACxB,MAAM,QAAQ,IAAI,OAAO;GACvB,IAAI;GACJ,mBAAmB;EACpB;AACD,SAAO,gBAAgB,MAAM,QAAQ,QAAQ,QAAQ,KAAK,EAAE,MAAM;AAClE,SAAO,gBAAgB,MAAM,QAAQ,QAAQ,QAAQ,EAAE,MAAM;AAC7D,SAAO,gBAAgB,MAAM,QAAQ,QAAQ,MAAM,EAAE,MAAM;CAC5D,EAAC;AAEF,MAAK,cAAc,YAAY;AAC7B,SAAO,gBAAgB,MAAM,QAAQ,QAAQ,QAAQ,QAAQ,KAAK,EAAE,MAAM;AAC1E,SAAO,gBAAgB,MAAM,QAAQ,QAAQ,QAAQ,QAAQ,EAAE,MAAM;AACrE,SAAO,gBACL,MAAM,QAAQ,QAAQ,MAAM,QAAQ,UAAU,CAAC,EAC/C,MACD;AACD,SAAO,gBAAgB,MAAM,QAAQ,QAAQ,QAAQ,YAAY,EAAE,MAAM;CAC1E,EAAC;AACH,EAAC;AAEF,KAAK,yBAAyB,OAAO,MAAM;CACzC,MAAM,KAAK,IAAI;CACf,MAAM,MAAM,IAAI,QAAc;EAAE;EAAI,UAAU;CAAO;CACrD,MAAM,MAAM,kBAAkB,KAAK,sBAAsB;CACzD,MAAM,UAAU,IAAI,YAAY,KAAK;AAErC,OAAM,EAAE,KAAK,UAAU,YAAY;AACjC,MAAI,iBAAiB,CAAE;EACvB,MAAM,YAAY,MAAM,QAAQ,QAAQ,KAAK,eAAe;AAC5D,SAAO,gBAAgB,IAAI,eAAe,QAAQ,EAAE;EACpD,MAAM,EAAE,YAAY,UAAU,GAAG,IAAI,eAAe;AACpD,SAAO,gBAAgB,YAAY,YAAY;AAC/C,SAAO,GAAG,oBAAoB,OAAO;AACrC,SAAO,gBAAgB,SAAS,SAAS,IAAI,YAAY,IAAI,WAAW,CAAC;AACzE,SAAO,gBAAgB,SAAS,OAAO,CAAC,iBAAkB,EAAC;AAC3D,SAAO,gBAAgB,SAAS,OAAO,CACrC,IAAI,gBAAgB,IAAI,WAAW,AACpC,EAAC;EACF,MAAM,SAAS,MAAM,SAAS,UAAU,IAAI;AAC5C,SAAO,GAAG,kBAAkB,KAAK;AACjC,SAAO,gBACL,OAAO,eACP,IAAI,YAAY,IAAI,WAAW,CAChC;AACD,SAAO,gBAAgB,OAAO,OAAO,CAAC,iBAAkB,EAAC;AACzD,SAAO,gBAAgB,OAAO,OAAO,CAAC,IAAI,gBAAgB,IAAI,WAAW,AAAC,EAAC;AAC3E,SAAO,gBAAgB,OAAO,SAAS,uBAAuB;AAC9D,SAAO,gBAAgB,OAAO,QAAQ,CAAE,EAAC;AACzC,SAAO,gBAAgB,UAAU,IAAI,OAAO,GAAG;AAC/C,SAAO,gBAAgB,UAAU,MAAM,gBAAgB;AACvD,SAAO,gBAAgB,UAAU,MAAM,uBAAuB;AAC9D,SAAO,gBAAgB,UAAU,YAAY,SAAS;AACtD,SAAO,gBAAgB,UAAU,UAAU,CAAE,EAAC;CAC/C,EAAC;AAEF,OAAM,EAAE,KAAK,YAAY,YAAY;AACnC,MAAI,iBAAiB,CAAE;EACvB,MAAM,cAAc,MAAM,QAAQ,QAAQ,KAAK,SAAS,EACtD,YAAY,WACb,EAAC;AACF,SAAO,gBAAgB,IAAI,eAAe,QAAQ,EAAE;EACpD,MAAM,EAAE,YAAY,UAAU,GAAG,IAAI,eAAe;AACpD,SAAO,gBAAgB,YAAY,YAAY;AAC/C,SAAO,GAAG,oBAAoB,OAAO;AACrC,SAAO,gBAAgB,SAAS,SAAS,IAAI,YAAY,IAAI,WAAW,CAAC;AACzE,SAAO,gBAAgB,SAAS,OAAO,CACrC,IAAI,gBAAgB,IAAI,WAAW,AACpC,EAAC;AACF,SAAO,gBAAgB,SAAS,OAAO,CAAC,iBAAkB,EAAC;EAC3D,MAAM,SAAS,MAAM,SAAS,UAAU,IAAI;AAC5C,SAAO,GAAG,kBAAkB,KAAK;AACjC,SAAO,gBACL,OAAO,eACP,IAAI,YAAY,IAAI,WAAW,CAChC;AACD,SAAO,gBAAgB,OAAO,OAAO,CAAC,IAAI,gBAAgB,IAAI,WAAW,AAAC,EAAC;AAC3E,SAAO,gBAAgB,OAAO,OAAO,CAAC,iBAAkB,EAAC;AACzD,SAAO,gBAAgB,OAAO,SAAS,gBAAgB;AACvD,SAAO,gBAAgB,OAAO,QAAQ,CAAE,EAAC;AACzC,SAAO,gBAAgB,YAAY,IAAI,OAAO,GAAG;AACjD,SAAO,gBAAgB,YAAY,MAAM,SAAS;AAClD,SAAO,gBAAgB,YAAY,MAAM,gBAAgB;AACzD,SAAO,gBAAgB,YAAY,YAAY,WAAW;AAC1D,SAAO,gBAAgB,YAAY,UAAU,CAAE,EAAC;CACjD,EAAC;AAEF,OAAM,EAAE,KAAK,aAAa,YAAY;AACpC,MAAI,iBAAiB,CAAE;EACvB,MAAM,eAAe,MAAM,QAAQ,QAAQ,KAAK,MAAM,EACpD,YAAY,YACb,EAAC;AACF,SAAO,gBAAgB,IAAI,eAAe,QAAQ,EAAE;EACpD,MAAM,EAAE,YAAY,UAAU,GAAG,IAAI,eAAe;AACpD,SAAO,gBAAgB,YAAY,YAAY;AAC/C,SAAO,GAAG,oBAAoB,OAAO;AACrC,SAAO,gBAAgB,SAAS,SAAS,IAAI,YAAY,IAAI,WAAW,CAAC;AACzE,SAAO,gBAAgB,SAAS,OAAO,CACrC,IAAI,gBAAgB,IAAI,WAAW,AACpC,EAAC;AACF,SAAO,gBAAgB,SAAS,OAAO,CAAE,EAAC;EAC1C,MAAM,SAAS,MAAM,SAAS,UAAU,IAAI;AAC5C,SAAO,GAAG,kBAAkB,KAAK;AACjC,SAAO,gBACL,OAAO,eACP,IAAI,YAAY,IAAI,WAAW,CAChC;AACD,SAAO,gBAAgB,OAAO,OAAO,CAAC,IAAI,gBAAgB,IAAI,WAAW,AAAC,EAAC;AAC3E,SAAO,gBAAgB,OAAO,OAAO,CAAE,EAAC;AACxC,SAAO,gBAAgB,OAAO,SAAS,aAAa;AACpD,SAAO,gBAAgB,OAAO,QAAQ,CAAE,EAAC;AACzC,SAAO,gBAAgB,aAAa,IAAI,OAAO,GAAG;AAClD,SAAO,gBAAgB,aAAa,MAAM,MAAM;AAChD,SAAO,gBAAgB,aAAa,MAAM,aAAa;AACvD,SAAO,gBAAgB,aAAa,YAAY,YAAY;AAC5D,SAAO,gBAAgB,aAAa,UAAU,CAAE,EAAC;CAClD,EAAC;AAEF,OAAM,EAAE,KAAK,UAAU,YAAY;EACjC,MAAM,YAAY,IAAI,OAAO;GAC3B,IAAI,IAAI,IAAI;GACZ,mBAAmB;EACpB;AACD,MAAI,iBAAiB,CAAE;EACvB,MAAM,YAAY,MAAM,QAAQ,QAC9B,KAAK,MAAM,QAAQ,UAAU,CAAC,IAC9B,EAAE,YAAY,SAAU,EACzB;AACD,SAAO,gBAAgB,IAAI,eAAe,QAAQ,EAAE;EACpD,MAAM,EAAE,YAAY,UAAU,GAAG,IAAI,eAAe;AACpD,SAAO,gBAAgB,YAAY,CAAC,SAAU,EAAC;AAC/C,SAAO,GAAG,oBAAoB,OAAO;AACrC,SAAO,gBAAgB,SAAS,SAAS,IAAI,YAAY,IAAI,WAAW,CAAC;AACzE,SAAO,gBAAgB,SAAS,OAAO,CAAC,UAAU,EAAG,EAAC;AACtD,SAAO,gBAAgB,SAAS,OAAO,CAAE,EAAC;EAC1C,MAAM,SAAS,MAAM,SAAS,UAAU,IAAI;AAC5C,SAAO,GAAG,kBAAkB,KAAK;AACjC,SAAO,gBACL,OAAO,eACP,IAAI,YAAY,IAAI,WAAW,CAChC;AACD,SAAO,gBAAgB,OAAO,OAAO,CAAC,UAAU,EAAG,EAAC;AACpD,SAAO,gBAAgB,OAAO,OAAO,CAAE,EAAC;AACxC,SAAO,gBACL,OAAO,SACP,iKAGD;EACD,MAAM,OAAO,MAAM,MAAM,UAAU,OAAO,SAAS,CAAC;AACpD,SAAO,gBAAgB,KAAK,QAAQ,EAAE;AACtC,SAAO,gBAAgB,UAAU,IAAI,OAAO,GAAG;AAC/C,SAAO,gBAAgB,UAAU,MAAM,yBAAyB;AAChE,SAAO,gBAAgB,UAAU,MAAM,OAAO,QAAQ;AACtD,SAAO,gBAAgB,UAAU,YAAY,SAAS;CAEvD,EAAC;AAEF,OAAM,EAAE,KAAK,SAAS,YAAY;EAChC,MAAM,iBAAiB,IAAI,OAAO;GAChC,IAAI,IAAI,IAAI;GACZ,mBAAmB;EACpB;EACD,MAAM,eAAe,IAAI,KAAK;GAC5B,IAAI,IAAI,IACN;GAEF,SAAS;GACT,aAAa;GACb,IAAI,IAAI,IAAI;GACZ,IAAI;EACL;EACD,MAAM,cAAc,MAAM,cACxB,cACA,SACA,CAAE,EACH;AACD,MAAI,iBAAiB,CAAE;EACvB,MAAM,QAAQ,MAAM,QAAQ,QAAQ,KAAK,kBAAkB,EACzD,aAAa,YACd,EAAC;AACF,SAAO,gBAAgB,IAAI,eAAe,QAAQ,EAAE;EACpD,MAAM,EAAE,YAAY,UAAU,GAAG,IAAI,eAAe;AACpD,SAAO,gBAAgB,YAAY,YAAY;AAC/C,SAAO,GAAG,oBAAoB,OAAO;AACrC,SAAO,gBAAgB,SAAS,SAAS,IAAI,YAAY,IAAI,WAAW,CAAC;AACzE,SAAO,gBAAgB,SAAS,OAAO,CAAC,iBAAkB,EAAC;AAC3D,SAAO,gBAAgB,SAAS,OAAO,CACrC,IAAI,gBAAgB,IAAI,WAAW,AACpC,EAAC;EACF,MAAM,SAAS,MAAM,SAAS,UAAU,IAAI;EAC5C,MAAM,EAAE,YAAY,aAAa,UAAU,WAAW,GACpD,IAAI,eAAe;AACrB,SAAO,gBAAgB,aAAa,CAAC,cAAe,EAAC;AACrD,SAAO,GAAG,qBAAqB,OAAO;AACtC,SAAO,gBAAgB,UAAU,SAAS,IAAI,YAAY,IAAI,WAAW,CAAC;AAC1E,SAAO,gBAAgB,UAAU,OAAO,CAAC,iBAAkB,EAAC;AAC5D,SAAO,gBAAgB,UAAU,OAAO,CACtC,IAAI,gBAAgB,IAAI,WAAW,AACpC,EAAC;AACF,SAAO,GAAG,kBAAkB,KAAK;AACjC,SAAO,gBACL,OAAO,eACP,IAAI,YAAY,IAAI,WAAW,CAChC;AACD,SAAO,gBAAgB,OAAO,OAAO,CAAC,iBAAkB,EAAC;AACzD,SAAO,gBAAgB,OAAO,OAAO,CAAC,IAAI,gBAAgB,IAAI,WAAW,AAAC,EAAC;AAC3E,SAAO,gBACL,OAAO,UACN;;2CAEoC,YAAY,GAAG,KAAK,IAAI,YAAY,GAAG,KAAK,UAClF;AACD,SAAO,gBAAgB,OAAO,UAAU,YAAY,GAAG;AACvD,SAAO,gBAAgB,MAAM,IAAI,OAAO,GAAG;AAC3C,SAAO,gBACL,MAAM,OACL,yBAAyB,YAAY,GAAG,KAAK,EAC/C;AACD,SAAO,gBACL,MAAM,OACL;;sBAEe,YAAY,GAAG,KAAK,IAAI,YAAY,GAAG,KAAK,UAC7D;AACD,SAAO,gBAAgB,MAAM,YAAY,SAAS;AAClD,SAAO,gBAAgB,MAAM,aAAa,IAAI,YAAY,GAAG;CAC9D,EAAC;AAEF,OAAM,EAAE,KAAK,sBAAsB,YAAY;AAC7C,MAAI,iBAAiB,CAAE;EACvB,MAAM,UAAU,SAAS,IAAI,SAAS,CAAC,IAAI,EAAE,OAAO,GAAI,EAAC;EACzD,MAAM,OAAO,MAAM,QAAQ,QAAQ,KAAK,8BAA8B;GACpE,OAAO;GACP,MAAM;IACJ,UAAU;IACV,SAAS;KAAC;KAAO;KAAQ;IAAQ;IACjC;GACD;EACF,EAAC;AACF,SAAO,gBAAgB,IAAI,eAAe,QAAQ,EAAE;EACpD,MAAM,EAAE,YAAY,UAAU,GAAG,IAAI,eAAe;AACpD,SAAO,gBAAgB,YAAY,YAAY;AAC/C,SAAO,GAAG,oBAAoB,OAAO;AACrC,SAAO,gBAAgB,SAAS,SAAS,IAAI,YAAY,IAAI,WAAW,CAAC;AACzE,SAAO,gBAAgB,SAAS,OAAO,CAAC,iBAAkB,EAAC;AAC3D,SAAO,gBAAgB,SAAS,OAAO,CACrC,IAAI,gBAAgB,IAAI,WAAW,AACpC,EAAC;EACF,MAAM,SAAS,MAAM,SAAS,UAAU,IAAI;AAC5C,SAAO,GAAG,kBAAkB,SAAS;AACrC,SAAO,gBACL,OAAO,eACP,IAAI,YAAY,IAAI,WAAW,CAChC;AACD,SAAO,gBAAgB,OAAO,OAAO,CAAC,iBAAkB,EAAC;AACzD,SAAO,gBAAgB,OAAO,OAAO,CAAC,IAAI,gBAAgB,IAAI,WAAW,AAAC,EAAC;AAC3E,SAAO,gBACL,OAAO,SACP,0CACD;AACD,SAAO,gBAAgB,OAAO,SAAS,QAAQ;AAC/C,SAAO,gBAAgB,OAAO,QAAQ,EAAE;AACxC,SAAO,gBAAgB,OAAO,oBAAoB,CAAE,EAAC;EAErD,MAAM,mBAAmB,MAAM,MAAM,UACnC,OAAO,oBAAoB,IAAI,CAChC;AACD,SAAO,gBAAgB,iBAAiB,QAAQ,EAAE;AAClD,SAAO,GAAG,iBAAiB,cAAc,KAAK;AAC9C,SAAO,gBAAgB,iBAAiB,GAAG,MAAM,UAAU,EAAE,MAAM;AACnE,SAAO,GAAG,iBAAiB,cAAc,KAAK;AAC9C,SAAO,gBAAgB,iBAAiB,GAAG,MAAM,UAAU,EAAE,OAAO;AACpE,SAAO,GAAG,iBAAiB,cAAc,KAAK;AAC9C,SAAO,gBAAgB,iBAAiB,GAAG,MAAM,UAAU,EAAE,QAAQ;AAErE,OAAK,MAAM,UAAU,kBAAkB;GACrC,MAAM,UAAU,MAAM,OAAO,WAAW,IAAI;AAC5C,UAAO,gBAAgB,SAAS,YAAY,EAAE;EAC/C;AAED,SAAO,gBAAgB,KAAK,IAAI,OAAO,GAAG;AAC1C,SAAO,gBAAgB,KAAK,MAAM,8BAA8B;AAChE,SAAO,gBACL,KAAK,MACL,0CACD;AACD,SAAO,gBAAgB,KAAK,YAAY,SAAS;CAClD,EAAC;AAEF,OAAM,EAAE,KAAK,wBAAwB,YAAY;AAC/C,MAAI,iBAAiB,CAAE;EACvB,MAAM,UAAU,SAAS,IAAI,SAAS,CAAC,IAAI,EAAE,OAAO,KAAK,EAAG,EAAC;EAC7D,MAAM,OAAO,MAAM,QAAQ,QACzB,KAAK,2CACL;GACE,OAAO;GACP,MAAM;IACJ,UAAU;IACV,SAAS;KAAC;KAAc;KAAc;KAAU;IAAO;IACvD;GACD;GACD,YAAY;EACb,EACF;AACD,SAAO,gBAAgB,IAAI,eAAe,QAAQ,EAAE;EACpD,MAAM,EAAE,YAAY,UAAU,GAAG,IAAI,eAAe;AACpD,SAAO,gBAAgB,YAAY,YAAY;AAC/C,SAAO,GAAG,oBAAoB,OAAO;EACrC,MAAM,SAAS,MAAM,SAAS,UAAU,IAAI;AAC5C,SAAO,GAAG,kBAAkB,SAAS;AACrC,SAAO,gBAAgB,OAAO,SAAS,QAAQ;AAC/C,SAAO,gBAAgB,OAAO,QAAQ,EAAE;AACxC,SAAO,gBAAgB,OAAO,oBAAoB,CAAE,EAAC;EAErD,MAAM,mBAAmB,MAAM,MAAM,UACnC,OAAO,oBAAoB,IAAI,CAChC;AACD,SAAO,gBAAgB,iBAAiB,QAAQ,EAAE;AAClD,SAAO,GAAG,iBAAiB,cAAc,KAAK;AAC9C,SAAO,gBAAgB,iBAAiB,GAAG,MAAM,UAAU,EAAE,aAAa;AAC1E,SAAO,GAAG,iBAAiB,cAAc,KAAK;AAC9C,SAAO,gBAAgB,iBAAiB,GAAG,MAAM,UAAU,EAAE,aAAa;AAC1E,SAAO,GAAG,iBAAiB,cAAc,KAAK;AAC9C,SAAO,gBAAgB,iBAAiB,GAAG,MAAM,UAAU,EAAE,SAAS;AACtE,SAAO,GAAG,iBAAiB,cAAc,KAAK;AAC9C,SAAO,gBAAgB,iBAAiB,GAAG,MAAM,UAAU,EAAE,OAAO;AAEpE,SAAO,gBAAgB,KAAK,YAAY,WAAW;AACnD,SAAO,gBAAgB,SAAS,OAAO,CACrC,IAAI,gBAAgB,IAAI,WAAW,AACpC,EAAC;AACF,SAAO,gBAAgB,SAAS,OAAO,CAAC,iBAAkB,EAAC;CAC5D,EAAC;AAEF,OAAM,EAAE,KAAK,+BAA+B,YAAY;EACtD,MAAM,YAAY,IAAI,OAAO;GAC3B,IAAI,IAAI,IAAI;GACZ,mBAAmB;EACpB;AACD,MAAI,iBAAiB,CAAE;EACvB,MAAM,UAAU,SAAS,IAAI,SAAS,CAAC,IAAI,EAAE,OAAO,GAAI,EAAC;EACzD,MAAM,OAAO,MAAM,QAAQ,QACzB,KAAK,MAAM,QAAQ,UAAU,CAAC,uBAC9B;GACE,OAAO;GACP,MAAM;IACJ,UAAU;IACV,SAAS;KAAC;KAAQ;KAAO;IAAU;IACnC;GACD;GACD,YAAY;EACb,EACF;AACD,SAAO,gBAAgB,IAAI,eAAe,QAAQ,EAAE;EACpD,MAAM,EAAE,YAAY,UAAU,GAAG,IAAI,eAAe;AACpD,SAAO,gBAAgB,YAAY,CAAC,SAAU,EAAC;AAC/C,SAAO,GAAG,oBAAoB,OAAO;EACrC,MAAM,SAAS,MAAM,SAAS,UAAU,IAAI;AAC5C,SAAO,GAAG,kBAAkB,SAAS;AACrC,SAAO,gBAAgB,OAAO,OAAO,CAAC,UAAU,EAAG,EAAC;AACpD,SAAO,gBAAgB,OAAO,OAAO,CAAE,EAAC;AACxC,SAAO,gBAAgB,KAAK,YAAY,SAAS;CAClD,EAAC;AAEF,OAAM,EAAE,KAAK,4BAA4B,YAAY;EAEnD,MAAM,kBAAkB,IAAI;EAC5B,MAAM,WAAW,IAAI,QAAc;GACjC,IAAI,IAAI;GACR,YAAY;GACZ,UAAU;EACX;EACD,MAAM,WAAW,kBAAkB,UAAU,sBAAsB;EACnE,MAAM,eAAe,IAAI,YAAY,UAAU;EAE/C,MAAM,UAAU,SAAS,IAAI,SAAS,CAAC,IAAI,EAAE,OAAO,EAAG,EAAC;EAGxD,MAAM,OAAO,MAAM,aAAa,QAC9B,KAAK,iCACL;GACE,OAAO;GACP,MAAM;IACJ,UAAU;IACV,SAAS;KAAC;KAAS;KAAW;IAAQ;IACtC;GACD;EACF,EACF;AAGD,SAAO,gBAAgB,SAAS,eAAe,QAAQ,EAAE;EACzD,MAAM,EAAE,UAAU,gBAAgB,GAAG,SAAS,eAAe;AAC7D,SAAO,GAAG,0BAA0B,OAAO;EAC3C,MAAM,aAAa,MAAM,eAAe,UAAU,SAAS;AAC3D,SAAO,GAAG,sBAAsB,SAAS;AACzC,SAAO,gBAAgB,WAAW,SAAS,QAAQ;EAGnD,MAAM,UAAU,MAAM,MAAM,UAC1B,WAAW,oBAAoB,SAAS,CACzC;AACD,SAAO,gBAAgB,QAAQ,QAAQ,EAAE;AACzC,SAAO,gBAAgB,QAAQ,GAAG,MAAM,UAAU,EAAE,QAAQ;AAC5D,SAAO,gBAAgB,QAAQ,GAAG,MAAM,UAAU,EAAE,UAAU;AAC9D,SAAO,gBAAgB,QAAQ,GAAG,MAAM,UAAU,EAAE,QAAQ;EAG5D,MAAM,SAAS,aAAa,UAAU,EAAE,OAAO,SAAU,EAAC;EAC1D,MAAM,WAAW,MAAM,MAAM,UAAU,OAAO;AAC9C,SAAO,gBAAgB,SAAS,QAAQ,EAAE;AAC1C,SAAO,gBAAgB,SAAS,GAAG,IAAI,KAAK,GAAG;AAC/C,SAAO,gBAAgB,SAAS,GAAG,MAAM,iCAAiC;AAG1E,SAAO,gBAAgB,KAAK,YAAY,SAAS;AACjD,SAAO,gBAAgB,KAAK,UAAU,CAAE,EAAC;CAC1C,EAAC;AACH,EAAC;AAEF,KAAK,2BAA2B,OAAO,MAAM;CAC3C,MAAM,aAAa,IAAI;CACvB,MAAM,MAAM,IAAI,QAAc;EAC5B,IAAI,IAAI;EACR;EACA,UAAU;CACX;CACD,MAAM,MAAM,kBAAkB,KAAK,sBAAsB;CACzD,MAAM,UAAU,IAAI,YAAY,KAAK;CAErC,MAAM,WAAW,IAAI,OAAO;EAC1B,IAAI,IAAI,IACN;EAEF,OAAO,IAAI,IAAI;EACf,IAAI,IAAI,IAAI;EACZ,IAAI;EACJ,QAAQ,IAAI,KAAK;GACf,IAAI,IAAI,IACN;GAEF,aAAa,IAAI,IAAI;GACrB,IAAI,IAAI,IAAI;GACZ,IAAI;GACJ,SAAS;GACT,WAAW,SAAS,QAAQ,KAAK,uBAAuB;EACzD;EACD,WAAW,SAAS,QAAQ,KAAK,uBAAuB;CACzD;CACD,MAAM,WAAW,IAAI,OAAO;EAC1B,IAAI,IAAI,IACN;EAEF,OAAO,IAAI,IAAI;EACf,IAAI,IAAI,IAAI;EACZ,IAAI;EACJ,QAAQ,IAAI,KAAK;GACf,IAAI,IAAI,IACN;GAEF,aAAa,IAAI,IAAI;GACrB,IAAI,IAAI,IAAI;GACZ,IAAI;GACJ,SAAS;GACT,WAAW,SAAS,QAAQ,KAAK,uBAAuB;EACzD;EACD,WAAW,SAAS,QAAQ,KAAK,uBAAuB;CACzD;CACD,MAAM,WAAW,IAAI,OAAO;EAC1B,IAAI,IAAI,IACN;EAEF,OAAO,IAAI,IAAI;EACf,IAAI,IAAI,IAAI;EACZ,IAAI;EACJ,QAAQ,IAAI,KAAK;GACf,IAAI,IAAI,IACN;GAEF,aAAa,IAAI,IAAI;GACrB,IAAI,IAAI,IAAI;GACZ,IAAI;GACJ,SAAS;GACT,WAAW,SAAS,QAAQ,KAAK,uBAAuB;EACzD;EACD,WAAW,SAAS,QAAQ,KAAK,uBAAuB;CACzD;CACD,MAAM,WAAW,IAAI,OAAO;EAC1B,IAAI,IAAI,IACN;EAEF,OAAO,IAAI,IAAI;EACf,IAAI,IAAI,IAAI;EACZ,IAAI;EACJ,QAAQ,IAAI,KAAK;GACf,IAAI,IAAI,IACN;GAEF,aAAa,IAAI,IAAI;GACrB,IAAI,IAAI,IAAI;GACZ,IAAI;GACJ,SAAS;GACT,WAAW,SAAS,QAAQ,KAAK,uBAAuB;EACzD;EACD,WAAW,SAAS,QAAQ,KAAK,uBAAuB;CACzD;AACD,OAAM,WAAW,WAAW,wCAAwC,SAAS;AAC7E,OAAM,WAAW,WAAW,wCAAwC,SAAS;AAC7E,OAAM,WAAW,WAAW,wCAAwC,SAAS;AAC7E,OAAM,WAAW,WAAW,wCAAwC,SAAS;AAE7E,OAAM,EAAE,KAAK,WAAW,YAAY;EAClC,MAAM,SAAS,QAAQ,UAAU,EAAE,OAAO,SAAU,EAAC;EACrD,MAAM,WAAW,MAAM,MAAM,UAAU,OAAO;AAC9C,SAAO,gBAAgB,SAAS,QAAQ,EAAE;AAE1C,SAAO,gBACL,SAAS,GAAG,GAAG,MACf,mEACD;AACD,SAAO,gBACL,SAAS,GAAG,MAAM,IAAI,MACtB,mCACD;AACD,SAAO,gBAAgB,SAAS,GAAG,YAAY,WAAW;AAC1D,SAAO,gBAAgB,SAAS,GAAG,MAAM,gBAAgB;AACzD,SAAO,gBACL,SAAS,GAAG,WACZ,SAAS,QAAQ,KAAK,uBAAuB,CAC9C;AAED,SAAO,gBACL,SAAS,GAAG,GAAG,MACf,mEACD;AACD,SAAO,gBACL,SAAS,GAAG,MAAM,IAAI,MACtB,mCACD;AACD,SAAO,gBAAgB,SAAS,GAAG,YAAY,WAAW;AAC1D,SAAO,gBAAgB,SAAS,GAAG,MAAM,gBAAgB;AACzD,SAAO,gBACL,SAAS,GAAG,WACZ,SAAS,QAAQ,KAAK,uBAAuB,CAC9C;AAED,SAAO,gBACL,SAAS,GAAG,GAAG,MACf,mEACD;AACD,SAAO,gBACL,SAAS,GAAG,MAAM,IAAI,MACtB,mCACD;AACD,SAAO,gBAAgB,SAAS,GAAG,YAAY,WAAW;AAC1D,SAAO,gBAAgB,SAAS,GAAG,MAAM,gBAAgB;AACzD,SAAO,gBACL,SAAS,GAAG,WACZ,SAAS,QAAQ,KAAK,uBAAuB,CAC9C;AAED,SAAO,gBACL,SAAS,GAAG,GAAG,MACf,mEACD;AACD,SAAO,gBACL,SAAS,GAAG,MAAM,IAAI,MACtB,mCACD;AACD,SAAO,gBAAgB,SAAS,GAAG,YAAY,WAAW;AAC1D,SAAO,gBAAgB,SAAS,GAAG,MAAM,gBAAgB;AACzD,SAAO,gBACL,SAAS,GAAG,WACZ,SAAS,QAAQ,KAAK,uBAAuB,CAC9C;CACF,EAAC;AAEF,OAAM,EAAE,KAAK,mBAAmB,YAAY;EAC1C,MAAM,SAAS,QAAQ,UAAU,EAAE,OAAO,SAAU,EAAC;EACrD,MAAM,WAAW,MAAM,MAAM,UAAU,OAAO;EAC9C,MAAM,aAAa,SAAS,IAAI,CAAC,QAAQ,IAAI,GAAG,KAAK;AACrD,SAAO,gBAAgB,YAAY;GACjC;GACA;GACA;GACA;EACD,EAAC;CACH,EAAC;AAEF,OAAM,EAAE,KAAK,mBAAmB,YAAY;EAC1C,MAAM,SAAS,QAAQ,UAAU,EAAE,OAAO,SAAU,EAAC;EACrD,MAAM,WAAW,MAAM,MAAM,UAAU,OAAO;EAC9C,MAAM,aAAa,SAAS,IAAI,CAAC,QAAQ,IAAI,GAAG,KAAK;AACrD,SAAO,gBAAgB,YAAY;GACjC;GACA;GACA;GACA;EACD,EAAC;CACH,EAAC;AAEF,OAAM,EAAE,KAAK,SAAS,YAAY;EAChC,MAAM,SAAS,QAAQ,UAAU,EAC/B,OAAO,SAAS,QAAQ,KAAK,uBAAuB,CACrD,EAAC;EACF,MAAM,WAAW,MAAM,MAAM,UAAU,OAAO;EAC9C,MAAM,aAAa,SAAS,IAAI,CAAC,QAAQ,IAAI,GAAG,KAAK;AACrD,SAAO,gBAAgB,YAAY,CACjC,oEACA,kEACD,EAAC;CACH,EAAC;AAEF,OAAM,EAAE,KAAK,SAAS,YAAY;EAChC,MAAM,SAAS,QAAQ,UAAU,EAC/B,OAAO,SAAS,QAAQ,KAAK,uBAAuB,CACrD,EAAC;EACF,MAAM,WAAW,MAAM,MAAM,UAAU,OAAO;EAC9C,MAAM,aAAa,SAAS,IAAI,CAAC,QAAQ,IAAI,GAAG,KAAK;AACrD,SAAO,gBAAgB,YAAY,CACjC,oEACA,kEACD,EAAC;CACH,EAAC;AACH,EAAC;AAWF,SAAgB,kBACdA,KACAC,QACa;CACb,MAAM,MAAM,IAAI,WAAW,cACzB,IAAI,IAAI,gBAET;AACD,KAAI,iBAAiB,CAAE;AACvB,KAAI,eAAe,CAAC,GAAG,YAAY,aAAa;AAC9C,MAAI,eAAe,KAAK;GACtB,YAAY,eAAe,cACvB,cACA,MAAM,QAAQ,WAAW,GACzB,aACA,CAAC,UAAW;GAChB;EACD,EAAC;AACF,SAAO,QAAQ,SAAS;CACzB;AACD,QAAO;AACR"}
|
|
1
|
+
{"version":3,"file":"session-impl.test.js","names":["bot: BotImpl<void>","origin: URL | string"],"sources":["../src/session-impl.test.ts"],"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/>.\nimport { type Context, MemoryKvStore } from \"@fedify/fedify/federation\";\nimport {\n type Activity,\n Create,\n Follow,\n Note,\n Person,\n PUBLIC_COLLECTION,\n Question,\n type Recipient,\n Undo,\n} from \"@fedify/fedify/vocab\";\nimport assert from \"node:assert\";\nimport { describe, test } from \"node:test\";\nimport { BotImpl } from \"./bot-impl.ts\";\nimport { createMessage } from \"./message-impl.ts\";\nimport { MemoryRepository, type Uuid } from \"./repository.ts\";\nimport { SessionImpl } from \"./session-impl.ts\";\nimport { mention, text } from \"./text.ts\";\n\ntest(\"SessionImpl.follow()\", async (t) => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = createMockContext(bot, \"https://example.com\");\n const session = new SessionImpl(bot, ctx);\n\n await t.test(\"follow\", async () => {\n const actor = new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n });\n await session.follow(actor);\n assert.deepStrictEqual(ctx.sentActivities.length, 1);\n const { recipients, activity } = ctx.sentActivities[0];\n assert.deepStrictEqual(recipients, [actor]);\n assert.ok(activity instanceof Follow);\n const parsed = ctx.parseUri(activity.id);\n assert.deepStrictEqual(parsed?.type, \"object\");\n assert.ok(parsed?.type === \"object\");\n assert.deepStrictEqual(parsed.class, Follow);\n assert.deepStrictEqual(activity.actorId, ctx.getActorUri(bot.identifier));\n assert.deepStrictEqual(activity.objectId, actor.id);\n assert.deepStrictEqual(activity.toIds, [actor.id]);\n const follow = await repository.getSentFollow(parsed.values.id as Uuid);\n assert.ok(follow != null);\n assert.deepStrictEqual(\n await follow.toJsonLd({ format: \"compact\" }),\n await activity.toJsonLd({ format: \"compact\" }),\n );\n });\n\n await t.test(\"follow again\", async () => {\n ctx.sentActivities = [];\n await repository.addFollowee(\n new URL(\"https://example.com/ap/actor/alice\"),\n new Follow({\n id: new URL(\n \"https://example.com/ap/follow/4114eadb-2596-408f-ad99-06f467c9ace0\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new URL(\"https://example.com/ap/actor/alice\"),\n }),\n );\n const actor = new Person({\n id: new URL(\"https://example.com/ap/actor/alice\"),\n preferredUsername: \"alice\",\n });\n await session.follow(actor);\n assert.deepStrictEqual(ctx.sentActivities, []);\n });\n\n await t.test(\"follow bot itself\", async () => {\n ctx.sentActivities = [];\n await assert.rejects(\n () => session.follow(session.actorId.href),\n TypeError,\n \"The bot cannot follow itself.\",\n );\n assert.deepStrictEqual(ctx.sentActivities, []);\n\n await assert.rejects(\n () => session.follow(session.actorId),\n TypeError,\n \"The bot cannot follow itself.\",\n );\n assert.deepStrictEqual(ctx.sentActivities, []);\n\n await assert.rejects(\n () => session.follow(session.actorHandle),\n TypeError,\n \"The bot cannot follow itself.\",\n );\n assert.deepStrictEqual(ctx.sentActivities, []);\n\n const actor = await session.getActor();\n await assert.rejects(\n () => session.follow(actor),\n TypeError,\n \"The bot cannot follow itself.\",\n );\n assert.deepStrictEqual(ctx.sentActivities, []);\n });\n});\n\ntest(\"SessionImpl.unfollow()\", async (t) => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = createMockContext(bot, \"https://example.com\");\n const session = new SessionImpl(bot, ctx);\n\n await t.test(\"unfollow\", async () => {\n await repository.addFollowee(\n new URL(\"https://example.com/ap/actor/alice\"),\n new Follow({\n id: new URL(\n \"https://example.com/ap/follow/4114eadb-2596-408f-ad99-06f467c9ace0\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new URL(\"https://example.com/ap/actor/alice\"),\n }),\n );\n const actor = new Person({\n id: new URL(\"https://example.com/ap/actor/alice\"),\n preferredUsername: \"alice\",\n });\n await session.unfollow(actor);\n assert.deepStrictEqual(ctx.sentActivities.length, 1);\n const { recipients, activity } = ctx.sentActivities[0];\n assert.deepStrictEqual(recipients, [actor]);\n assert.ok(activity instanceof Undo);\n const object = await activity.getObject(ctx);\n assert.ok(object instanceof Follow);\n assert.deepStrictEqual(\n object.id,\n new URL(\n \"https://example.com/ap/follow/4114eadb-2596-408f-ad99-06f467c9ace0\",\n ),\n );\n assert.deepStrictEqual(object.actorId, ctx.getActorUri(bot.identifier));\n assert.deepStrictEqual(\n await repository.getFollowee(\n new URL(\"https://example.com/ap/actor/alice\"),\n ),\n undefined,\n );\n });\n\n await t.test(\"unfollow again\", async () => {\n ctx.sentActivities = [];\n const actor = new Person({\n id: new URL(\"https://example.com/ap/actor/alice\"),\n preferredUsername: \"alice\",\n });\n await session.unfollow(actor);\n assert.deepStrictEqual(ctx.sentActivities, []);\n });\n\n await t.test(\"unfollow bot itself\", async () => {\n ctx.sentActivities = [];\n await assert.rejects(\n () => session.unfollow(session.actorId.href),\n TypeError,\n \"The bot cannot unfollow itself.\",\n );\n assert.deepStrictEqual(ctx.sentActivities, []);\n\n await assert.rejects(\n () => session.unfollow(session.actorId),\n TypeError,\n \"The bot cannot unfollow itself.\",\n );\n assert.deepStrictEqual(ctx.sentActivities, []);\n\n await assert.rejects(\n () => session.unfollow(session.actorHandle),\n TypeError,\n \"The bot cannot unfollow itself.\",\n );\n assert.deepStrictEqual(ctx.sentActivities, []);\n\n const actor = await session.getActor();\n await assert.rejects(\n () => session.unfollow(actor),\n TypeError,\n \"The bot cannot unfollow itself.\",\n );\n assert.deepStrictEqual(ctx.sentActivities, []);\n });\n});\n\ndescribe(\"SessionImpl.follows()\", () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = createMockContext(bot, \"https://example.com\");\n const session = new SessionImpl(bot, ctx);\n\n test(\"when it follows\", async () => {\n const followeeId = new URL(\"https://example.com/ap/actor/alice\");\n const followee = new Person({\n id: followeeId,\n preferredUsername: \"alice\",\n });\n await repository.addFollowee(\n new URL(\"https://example.com/ap/actor/alice\"),\n new Follow({\n id: new URL(\n \"https://example.com/ap/follow/4114eadb-2596-408f-ad99-06f467c9ace0\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: followee,\n }),\n );\n assert.ok(await session.follows(followeeId.href));\n assert.ok(await session.follows(followeeId));\n assert.ok(await session.follows(followee));\n });\n\n test(\"when it does not follow\", async () => {\n const actorId = new URL(\"https://example.com/ap/actor/john\");\n const actor = new Person({\n id: actorId,\n preferredUsername: \"john\",\n });\n assert.deepStrictEqual(await session.follows(actorId.href), false);\n assert.deepStrictEqual(await session.follows(actorId), false);\n assert.deepStrictEqual(await session.follows(actor), false);\n });\n\n test(\"bot itself\", async () => {\n assert.deepStrictEqual(await session.follows(session.actorId.href), false);\n assert.deepStrictEqual(await session.follows(session.actorId), false);\n assert.deepStrictEqual(\n await session.follows(await session.getActor()),\n false,\n );\n assert.deepStrictEqual(await session.follows(session.actorHandle), false);\n });\n});\n\ntest(\"SessionImpl.publish()\", async (t) => {\n const kv = new MemoryKvStore();\n const bot = new BotImpl<void>({ kv, username: \"bot\" });\n const ctx = createMockContext(bot, \"https://example.com\");\n const session = new SessionImpl(bot, ctx);\n\n await t.test(\"public\", async () => {\n ctx.sentActivities = [];\n const publicMsg = await session.publish(text`Hello, world!`);\n assert.deepStrictEqual(ctx.sentActivities.length, 1);\n const { recipients, activity } = ctx.sentActivities[0];\n assert.deepStrictEqual(recipients, \"followers\");\n assert.ok(activity instanceof Create);\n assert.deepStrictEqual(activity.actorId, ctx.getActorUri(bot.identifier));\n assert.deepStrictEqual(activity.toIds, [PUBLIC_COLLECTION]);\n assert.deepStrictEqual(activity.ccIds, [\n ctx.getFollowersUri(bot.identifier),\n ]);\n const object = await activity.getObject(ctx);\n assert.ok(object instanceof Note);\n assert.deepStrictEqual(\n object.attributionId,\n ctx.getActorUri(bot.identifier),\n );\n assert.deepStrictEqual(object.toIds, [PUBLIC_COLLECTION]);\n assert.deepStrictEqual(object.ccIds, [ctx.getFollowersUri(bot.identifier)]);\n assert.deepStrictEqual(object.content, \"<p>Hello, world!</p>\");\n assert.deepStrictEqual(object.tagIds, []);\n assert.deepStrictEqual(publicMsg.id, object.id);\n assert.deepStrictEqual(publicMsg.text, \"Hello, world!\");\n assert.deepStrictEqual(publicMsg.html, \"<p>Hello, world!</p>\");\n assert.deepStrictEqual(publicMsg.visibility, \"public\");\n assert.deepStrictEqual(publicMsg.mentions, []);\n });\n\n await t.test(\"unlisted\", async () => {\n ctx.sentActivities = [];\n const unlistedMsg = await session.publish(text`Hello!`, {\n visibility: \"unlisted\",\n });\n assert.deepStrictEqual(ctx.sentActivities.length, 1);\n const { recipients, activity } = ctx.sentActivities[0];\n assert.deepStrictEqual(recipients, \"followers\");\n assert.ok(activity instanceof Create);\n assert.deepStrictEqual(activity.actorId, ctx.getActorUri(bot.identifier));\n assert.deepStrictEqual(activity.toIds, [\n ctx.getFollowersUri(bot.identifier),\n ]);\n assert.deepStrictEqual(activity.ccIds, [PUBLIC_COLLECTION]);\n const object = await activity.getObject(ctx);\n assert.ok(object instanceof Note);\n assert.deepStrictEqual(\n object.attributionId,\n ctx.getActorUri(bot.identifier),\n );\n assert.deepStrictEqual(object.toIds, [ctx.getFollowersUri(bot.identifier)]);\n assert.deepStrictEqual(object.ccIds, [PUBLIC_COLLECTION]);\n assert.deepStrictEqual(object.content, \"<p>Hello!</p>\");\n assert.deepStrictEqual(object.tagIds, []);\n assert.deepStrictEqual(unlistedMsg.id, object.id);\n assert.deepStrictEqual(unlistedMsg.text, \"Hello!\");\n assert.deepStrictEqual(unlistedMsg.html, \"<p>Hello!</p>\");\n assert.deepStrictEqual(unlistedMsg.visibility, \"unlisted\");\n assert.deepStrictEqual(unlistedMsg.mentions, []);\n });\n\n await t.test(\"followers\", async () => {\n ctx.sentActivities = [];\n const followersMsg = await session.publish(text`Hi!`, {\n visibility: \"followers\",\n });\n assert.deepStrictEqual(ctx.sentActivities.length, 1);\n const { recipients, activity } = ctx.sentActivities[0];\n assert.deepStrictEqual(recipients, \"followers\");\n assert.ok(activity instanceof Create);\n assert.deepStrictEqual(activity.actorId, ctx.getActorUri(bot.identifier));\n assert.deepStrictEqual(activity.toIds, [\n ctx.getFollowersUri(bot.identifier),\n ]);\n assert.deepStrictEqual(activity.ccIds, []);\n const object = await activity.getObject(ctx);\n assert.ok(object instanceof Note);\n assert.deepStrictEqual(\n object.attributionId,\n ctx.getActorUri(bot.identifier),\n );\n assert.deepStrictEqual(object.toIds, [ctx.getFollowersUri(bot.identifier)]);\n assert.deepStrictEqual(object.ccIds, []);\n assert.deepStrictEqual(object.content, \"<p>Hi!</p>\");\n assert.deepStrictEqual(object.tagIds, []);\n assert.deepStrictEqual(followersMsg.id, object.id);\n assert.deepStrictEqual(followersMsg.text, \"Hi!\");\n assert.deepStrictEqual(followersMsg.html, \"<p>Hi!</p>\");\n assert.deepStrictEqual(followersMsg.visibility, \"followers\");\n assert.deepStrictEqual(followersMsg.mentions, []);\n });\n\n await t.test(\"direct\", async () => {\n const mentioned = new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n });\n ctx.sentActivities = [];\n const directMsg = await session.publish(\n text`Hey ${mention(mentioned)}!`,\n { visibility: \"direct\" },\n );\n assert.deepStrictEqual(ctx.sentActivities.length, 1);\n const { recipients, activity } = ctx.sentActivities[0];\n assert.deepStrictEqual(recipients, [mentioned]);\n assert.ok(activity instanceof Create);\n assert.deepStrictEqual(activity.actorId, ctx.getActorUri(bot.identifier));\n assert.deepStrictEqual(activity.toIds, [mentioned.id]);\n assert.deepStrictEqual(activity.ccIds, []);\n const object = await activity.getObject(ctx);\n assert.ok(object instanceof Note);\n assert.deepStrictEqual(\n object.attributionId,\n ctx.getActorUri(bot.identifier),\n );\n assert.deepStrictEqual(object.toIds, [mentioned.id]);\n assert.deepStrictEqual(object.ccIds, []);\n assert.deepStrictEqual(\n object.content,\n '<p>Hey <a href=\"https://example.com/ap/actor/john\" translate=\"no\" ' +\n 'class=\"h-card u-url mention\" target=\"_blank\">@<span>john@example.com' +\n \"</span></a>!</p>\",\n );\n const tags = await Array.fromAsync(object.getTags());\n assert.deepStrictEqual(tags.length, 1);\n assert.deepStrictEqual(directMsg.id, object.id);\n assert.deepStrictEqual(directMsg.text, \"Hey @john@example.com!\");\n assert.deepStrictEqual(directMsg.html, object.content);\n assert.deepStrictEqual(directMsg.visibility, \"direct\");\n // assert.deepStrictEqual(directMsg.mentions, [mentioned]); // FIXME\n });\n\n await t.test(\"quote\", async () => {\n const originalAuthor = new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n });\n const originalPost = new Note({\n id: new URL(\n \"https://example.com/ap/note/c1c792ce-a0be-4685-b396-e59e5ef8c788\",\n ),\n content: \"<p>Hello, world!</p>\",\n attribution: originalAuthor,\n to: new URL(\"https://example.com/ap/actor/john/followers\"),\n cc: PUBLIC_COLLECTION,\n });\n const originalMsg = await createMessage<Note, void>(\n originalPost,\n session,\n {},\n );\n ctx.sentActivities = [];\n const quote = await session.publish(text`Check this out!`, {\n quoteTarget: originalMsg,\n });\n assert.deepStrictEqual(ctx.sentActivities.length, 2);\n const { recipients, activity } = ctx.sentActivities[0];\n assert.deepStrictEqual(recipients, \"followers\");\n assert.ok(activity instanceof Create);\n assert.deepStrictEqual(activity.actorId, ctx.getActorUri(bot.identifier));\n assert.deepStrictEqual(activity.toIds, [PUBLIC_COLLECTION]);\n assert.deepStrictEqual(activity.ccIds, [\n ctx.getFollowersUri(bot.identifier),\n ]);\n const object = await activity.getObject(ctx);\n const { recipients: recipients2, activity: activity2 } =\n ctx.sentActivities[1];\n assert.deepStrictEqual(recipients2, [originalAuthor]);\n assert.ok(activity2 instanceof Create);\n assert.deepStrictEqual(activity2.actorId, ctx.getActorUri(bot.identifier));\n assert.deepStrictEqual(activity2.toIds, [PUBLIC_COLLECTION]);\n assert.deepStrictEqual(activity2.ccIds, [\n ctx.getFollowersUri(bot.identifier),\n ]);\n assert.ok(object instanceof Note);\n assert.deepStrictEqual(\n object.attributionId,\n ctx.getActorUri(bot.identifier),\n );\n assert.deepStrictEqual(object.toIds, [PUBLIC_COLLECTION]);\n assert.deepStrictEqual(object.ccIds, [ctx.getFollowersUri(bot.identifier)]);\n assert.deepStrictEqual(\n object.content,\n `<p>Check this out!</p>\n\n<p class=\"quote-inline\"><br>RE: <a href=\"${originalMsg.id.href}\">${originalMsg.id.href}</a></p>`,\n );\n assert.deepStrictEqual(object.quoteUrl, originalMsg.id);\n assert.deepStrictEqual(quote.id, object.id);\n assert.deepStrictEqual(\n quote.text,\n `Check this out!\\n\\nRE: ${originalMsg.id.href}`,\n );\n assert.deepStrictEqual(\n quote.html,\n `<p>Check this out!</p>\n\n<p><br>RE: <a href=\"${originalMsg.id.href}\">${originalMsg.id.href}</a></p>`,\n );\n assert.deepStrictEqual(quote.visibility, \"public\");\n assert.deepStrictEqual(quote.quoteTarget?.id, originalMsg.id);\n });\n\n await t.test(\"poll single choice\", async () => {\n ctx.sentActivities = [];\n const endTime = Temporal.Now.instant().add({ hours: 24 });\n const poll = await session.publish(text`What's your favorite color?`, {\n class: Question,\n poll: {\n multiple: false,\n options: [\"Red\", \"Blue\", \"Green\"],\n endTime,\n },\n });\n assert.deepStrictEqual(ctx.sentActivities.length, 1);\n const { recipients, activity } = ctx.sentActivities[0];\n assert.deepStrictEqual(recipients, \"followers\");\n assert.ok(activity instanceof Create);\n assert.deepStrictEqual(activity.actorId, ctx.getActorUri(bot.identifier));\n assert.deepStrictEqual(activity.toIds, [PUBLIC_COLLECTION]);\n assert.deepStrictEqual(activity.ccIds, [\n ctx.getFollowersUri(bot.identifier),\n ]);\n const object = await activity.getObject(ctx);\n assert.ok(object instanceof Question);\n assert.deepStrictEqual(\n object.attributionId,\n ctx.getActorUri(bot.identifier),\n );\n assert.deepStrictEqual(object.toIds, [PUBLIC_COLLECTION]);\n assert.deepStrictEqual(object.ccIds, [ctx.getFollowersUri(bot.identifier)]);\n assert.deepStrictEqual(\n object.content,\n \"<p>What's your favorite color?</p>\",\n );\n assert.deepStrictEqual(object.endTime, endTime);\n assert.deepStrictEqual(object.voters, 0);\n assert.deepStrictEqual(object.inclusiveOptionIds, []);\n\n const exclusiveOptions = await Array.fromAsync(\n object.getExclusiveOptions(ctx),\n );\n assert.deepStrictEqual(exclusiveOptions.length, 3);\n assert.ok(exclusiveOptions[0] instanceof Note);\n assert.deepStrictEqual(exclusiveOptions[0].name?.toString(), \"Red\");\n assert.ok(exclusiveOptions[1] instanceof Note);\n assert.deepStrictEqual(exclusiveOptions[1].name?.toString(), \"Blue\");\n assert.ok(exclusiveOptions[2] instanceof Note);\n assert.deepStrictEqual(exclusiveOptions[2].name?.toString(), \"Green\");\n\n for (const option of exclusiveOptions) {\n const replies = await option.getReplies(ctx);\n assert.deepStrictEqual(replies?.totalItems, 0);\n }\n\n assert.deepStrictEqual(poll.id, object.id);\n assert.deepStrictEqual(poll.text, \"What's your favorite color?\");\n assert.deepStrictEqual(\n poll.html,\n \"<p>What's your favorite color?</p>\",\n );\n assert.deepStrictEqual(poll.visibility, \"public\");\n });\n\n await t.test(\"poll multiple choice\", async () => {\n ctx.sentActivities = [];\n const endTime = Temporal.Now.instant().add({ hours: 24 * 7 });\n const poll = await session.publish(\n text`Which programming languages do you know?`,\n {\n class: Question,\n poll: {\n multiple: true,\n options: [\"JavaScript\", \"TypeScript\", \"Python\", \"Rust\"],\n endTime,\n },\n visibility: \"unlisted\",\n },\n );\n assert.deepStrictEqual(ctx.sentActivities.length, 1);\n const { recipients, activity } = ctx.sentActivities[0];\n assert.deepStrictEqual(recipients, \"followers\");\n assert.ok(activity instanceof Create);\n const object = await activity.getObject(ctx);\n assert.ok(object instanceof Question);\n assert.deepStrictEqual(object.endTime, endTime);\n assert.deepStrictEqual(object.voters, 0);\n assert.deepStrictEqual(object.exclusiveOptionIds, []);\n\n const inclusiveOptions = await Array.fromAsync(\n object.getInclusiveOptions(ctx),\n );\n assert.deepStrictEqual(inclusiveOptions.length, 4);\n assert.ok(inclusiveOptions[0] instanceof Note);\n assert.deepStrictEqual(inclusiveOptions[0].name?.toString(), \"JavaScript\");\n assert.ok(inclusiveOptions[1] instanceof Note);\n assert.deepStrictEqual(inclusiveOptions[1].name?.toString(), \"TypeScript\");\n assert.ok(inclusiveOptions[2] instanceof Note);\n assert.deepStrictEqual(inclusiveOptions[2].name?.toString(), \"Python\");\n assert.ok(inclusiveOptions[3] instanceof Note);\n assert.deepStrictEqual(inclusiveOptions[3].name?.toString(), \"Rust\");\n\n assert.deepStrictEqual(poll.visibility, \"unlisted\");\n assert.deepStrictEqual(activity.toIds, [\n ctx.getFollowersUri(bot.identifier),\n ]);\n assert.deepStrictEqual(activity.ccIds, [PUBLIC_COLLECTION]);\n });\n\n await t.test(\"poll with direct visibility\", async () => {\n const mentioned = new Person({\n id: new URL(\"https://example.com/ap/actor/alice\"),\n preferredUsername: \"alice\",\n });\n ctx.sentActivities = [];\n const endTime = Temporal.Now.instant().add({ hours: 12 });\n const poll = await session.publish(\n text`Hey ${mention(mentioned)}, what do you think?`,\n {\n class: Question,\n poll: {\n multiple: false,\n options: [\"Good\", \"Bad\", \"Neutral\"],\n endTime,\n },\n visibility: \"direct\",\n },\n );\n assert.deepStrictEqual(ctx.sentActivities.length, 1);\n const { recipients, activity } = ctx.sentActivities[0];\n assert.deepStrictEqual(recipients, [mentioned]);\n assert.ok(activity instanceof Create);\n const object = await activity.getObject(ctx);\n assert.ok(object instanceof Question);\n assert.deepStrictEqual(object.toIds, [mentioned.id]);\n assert.deepStrictEqual(object.ccIds, []);\n assert.deepStrictEqual(poll.visibility, \"direct\");\n });\n\n await t.test(\"poll end-to-end workflow\", async () => {\n // Create fresh repository and session for isolation\n const freshRepository = new MemoryRepository();\n const freshBot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository: freshRepository,\n username: \"testbot\",\n });\n const freshCtx = createMockContext(freshBot, \"https://example.com\");\n const freshSession = new SessionImpl(freshBot, freshCtx);\n\n const endTime = Temporal.Now.instant().add({ hours: 1 });\n\n // 1. Create a poll\n const poll = await freshSession.publish(\n text`What should we have for lunch?`,\n {\n class: Question,\n poll: {\n multiple: false,\n options: [\"Pizza\", \"Burgers\", \"Salad\"],\n endTime,\n },\n },\n );\n\n // Verify poll was created correctly\n assert.deepStrictEqual(freshCtx.sentActivities.length, 1);\n const { activity: createActivity } = freshCtx.sentActivities[0];\n assert.ok(createActivity instanceof Create);\n const pollObject = await createActivity.getObject(freshCtx);\n assert.ok(pollObject instanceof Question);\n assert.deepStrictEqual(pollObject.endTime, endTime);\n\n // Get poll options\n const options = await Array.fromAsync(\n pollObject.getExclusiveOptions(freshCtx),\n );\n assert.deepStrictEqual(options.length, 3);\n assert.deepStrictEqual(options[0].name?.toString(), \"Pizza\");\n assert.deepStrictEqual(options[1].name?.toString(), \"Burgers\");\n assert.deepStrictEqual(options[2].name?.toString(), \"Salad\");\n\n // 2. Verify poll is accessible via getOutbox\n const outbox = freshSession.getOutbox({ order: \"newest\" });\n const messages = await Array.fromAsync(outbox);\n assert.deepStrictEqual(messages.length, 1);\n assert.deepStrictEqual(messages[0].id, poll.id);\n assert.deepStrictEqual(messages[0].text, \"What should we have for lunch?\");\n\n // 3. Verify poll structure\n assert.deepStrictEqual(poll.visibility, \"public\");\n assert.deepStrictEqual(poll.mentions, []);\n });\n});\n\ntest(\"SessionImpl.getOutbox()\", async (t) => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"bot\",\n });\n const ctx = createMockContext(bot, \"https://example.com\");\n const session = new SessionImpl(bot, ctx);\n\n const messageA = new Create({\n id: new URL(\n \"https://example.com/ap/create/01941f29-7c00-7fe8-ab0a-7b593990a3c0\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/01941f29-7c00-7fe8-ab0a-7b593990a3c0\",\n ),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n content: \"Hello, world!\",\n published: Temporal.Instant.from(\"2025-01-01T00:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-01T00:00:00Z\"),\n });\n const messageB = new Create({\n id: new URL(\n \"https://example.com/ap/create/0194244f-d800-7873-8993-ef71ccd47306\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/0194244f-d800-7873-8993-ef71ccd47306\",\n ),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n content: \"Hello, world!\",\n published: Temporal.Instant.from(\"2025-01-02T00:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-02T00:00:00Z\"),\n });\n const messageC = new Create({\n id: new URL(\n \"https://example.com/ap/create/01942976-3400-7f34-872e-2cbf0f9eeac4\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/01942976-3400-7f34-872e-2cbf0f9eeac4\",\n ),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n content: \"Hello, world!\",\n published: Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n });\n const messageD = new Create({\n id: new URL(\n \"https://example.com/ap/create/01942e9c-9000-7480-a553-7a6ce737ce14\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/01942e9c-9000-7480-a553-7a6ce737ce14\",\n ),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n content: \"Hello, world!\",\n published: Temporal.Instant.from(\"2025-01-04T00:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-04T00:00:00Z\"),\n });\n await repository.addMessage(\"01941f29-7c00-7fe8-ab0a-7b593990a3c0\", messageA);\n await repository.addMessage(\"0194244f-d800-7873-8993-ef71ccd47306\", messageB);\n await repository.addMessage(\"01942976-3400-7f34-872e-2cbf0f9eeac4\", messageC);\n await repository.addMessage(\"01942e9c-9000-7480-a553-7a6ce737ce14\", messageD);\n\n await t.test(\"default\", async () => {\n const outbox = session.getOutbox({ order: \"oldest\" });\n const messages = await Array.fromAsync(outbox);\n assert.deepStrictEqual(messages.length, 4);\n\n assert.deepStrictEqual(\n messages[0].id.href,\n \"https://example.com/ap/note/01941f29-7c00-7fe8-ab0a-7b593990a3c0\",\n );\n assert.deepStrictEqual(\n messages[0].actor.id?.href,\n \"https://example.com/ap/actor/bot\",\n );\n assert.deepStrictEqual(messages[0].visibility, \"unlisted\");\n assert.deepStrictEqual(messages[0].text, \"Hello, world!\");\n assert.deepStrictEqual(\n messages[0].published,\n Temporal.Instant.from(\"2025-01-01T00:00:00Z\"),\n );\n\n assert.deepStrictEqual(\n messages[1].id.href,\n \"https://example.com/ap/note/0194244f-d800-7873-8993-ef71ccd47306\",\n );\n assert.deepStrictEqual(\n messages[1].actor.id?.href,\n \"https://example.com/ap/actor/bot\",\n );\n assert.deepStrictEqual(messages[1].visibility, \"unlisted\");\n assert.deepStrictEqual(messages[1].text, \"Hello, world!\");\n assert.deepStrictEqual(\n messages[1].published,\n Temporal.Instant.from(\"2025-01-02T00:00:00Z\"),\n );\n\n assert.deepStrictEqual(\n messages[2].id.href,\n \"https://example.com/ap/note/01942976-3400-7f34-872e-2cbf0f9eeac4\",\n );\n assert.deepStrictEqual(\n messages[2].actor.id?.href,\n \"https://example.com/ap/actor/bot\",\n );\n assert.deepStrictEqual(messages[2].visibility, \"unlisted\");\n assert.deepStrictEqual(messages[2].text, \"Hello, world!\");\n assert.deepStrictEqual(\n messages[2].published,\n Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n );\n\n assert.deepStrictEqual(\n messages[3].id.href,\n \"https://example.com/ap/note/01942e9c-9000-7480-a553-7a6ce737ce14\",\n );\n assert.deepStrictEqual(\n messages[3].actor.id?.href,\n \"https://example.com/ap/actor/bot\",\n );\n assert.deepStrictEqual(messages[3].visibility, \"unlisted\");\n assert.deepStrictEqual(messages[3].text, \"Hello, world!\");\n assert.deepStrictEqual(\n messages[3].published,\n Temporal.Instant.from(\"2025-01-04T00:00:00Z\"),\n );\n });\n\n await t.test(\"order: 'oldest'\", async () => {\n const outbox = session.getOutbox({ order: \"oldest\" });\n const messages = await Array.fromAsync(outbox);\n const messageIds = messages.map((msg) => msg.id.href);\n assert.deepStrictEqual(messageIds, [\n \"https://example.com/ap/note/01941f29-7c00-7fe8-ab0a-7b593990a3c0\",\n \"https://example.com/ap/note/0194244f-d800-7873-8993-ef71ccd47306\",\n \"https://example.com/ap/note/01942976-3400-7f34-872e-2cbf0f9eeac4\",\n \"https://example.com/ap/note/01942e9c-9000-7480-a553-7a6ce737ce14\",\n ]);\n });\n\n await t.test(\"order: 'newest'\", async () => {\n const outbox = session.getOutbox({ order: \"newest\" });\n const messages = await Array.fromAsync(outbox);\n const messageIds = messages.map((msg) => msg.id.href);\n assert.deepStrictEqual(messageIds, [\n \"https://example.com/ap/note/01942e9c-9000-7480-a553-7a6ce737ce14\",\n \"https://example.com/ap/note/01942976-3400-7f34-872e-2cbf0f9eeac4\",\n \"https://example.com/ap/note/0194244f-d800-7873-8993-ef71ccd47306\",\n \"https://example.com/ap/note/01941f29-7c00-7fe8-ab0a-7b593990a3c0\",\n ]);\n });\n\n await t.test(\"since\", async () => {\n const outbox = session.getOutbox({\n since: Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n });\n const messages = await Array.fromAsync(outbox);\n const messageIds = messages.map((msg) => msg.id.href);\n assert.deepStrictEqual(messageIds, [\n \"https://example.com/ap/note/01942e9c-9000-7480-a553-7a6ce737ce14\",\n \"https://example.com/ap/note/01942976-3400-7f34-872e-2cbf0f9eeac4\",\n ]);\n });\n\n await t.test(\"until\", async () => {\n const outbox = session.getOutbox({\n until: Temporal.Instant.from(\"2025-01-02T00:00:00Z\"),\n });\n const messages = await Array.fromAsync(outbox);\n const messageIds = messages.map((msg) => msg.id.href);\n assert.deepStrictEqual(messageIds, [\n \"https://example.com/ap/note/0194244f-d800-7873-8993-ef71ccd47306\",\n \"https://example.com/ap/note/01941f29-7c00-7fe8-ab0a-7b593990a3c0\",\n ]);\n });\n\n await t.test(\"messages should have update and delete methods\", async () => {\n const outbox = session.getOutbox({ order: \"oldest\" });\n const messages = await Array.fromAsync(outbox);\n assert.strictEqual(messages.length, 4);\n\n for (const message of messages) {\n assert.strictEqual(typeof message.update, \"function\");\n assert.strictEqual(typeof message.delete, \"function\");\n }\n });\n});\n\nexport interface SentActivity {\n recipients: \"followers\" | Recipient[];\n activity: Activity;\n}\n\nexport interface MockContext extends Context<void> {\n sentActivities: SentActivity[];\n}\n\nexport function createMockContext(\n bot: BotImpl<void>,\n origin: URL | string,\n): MockContext {\n const ctx = bot.federation.createContext(\n new URL(origin),\n undefined,\n ) as MockContext;\n ctx.sentActivities = [];\n ctx.sendActivity = (_, recipients, activity) => {\n ctx.sentActivities.push({\n recipients: recipients === \"followers\"\n ? \"followers\"\n : Array.isArray(recipients)\n ? recipients\n : [recipients],\n activity,\n });\n return Promise.resolve();\n };\n return ctx;\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fedify/botkit",
|
|
3
|
-
"version": "0.3.0-dev.
|
|
3
|
+
"version": "0.3.0-dev.125+e95bf3e4",
|
|
4
4
|
"description": "A framework for creating ActivityPub bots",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"author": {
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
"README.md"
|
|
129
129
|
],
|
|
130
130
|
"dependencies": {
|
|
131
|
-
"@fedify/fedify": "
|
|
131
|
+
"@fedify/fedify": "1.8.1-dev.1262",
|
|
132
132
|
"@fedify/markdown-it-hashtag": "^0.3.0",
|
|
133
133
|
"@fedify/markdown-it-mention": "^0.3.0",
|
|
134
134
|
"@js-temporal/polyfill": "^0.5.1",
|