@fedify/botkit 0.3.0-dev.108
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.md +75 -0
- package/dist/bot-impl.d.ts +111 -0
- package/dist/bot-impl.d.ts.map +1 -0
- package/dist/bot-impl.js +602 -0
- package/dist/bot-impl.js.map +1 -0
- package/dist/bot-impl.test.d.ts +2 -0
- package/dist/bot-impl.test.js +1642 -0
- package/dist/bot-impl.test.js.map +1 -0
- package/dist/bot.d.ts +270 -0
- package/dist/bot.d.ts.map +1 -0
- package/dist/bot.js +118 -0
- package/dist/bot.js.map +1 -0
- package/dist/bot.test.d.ts +2 -0
- package/dist/bot.test.js +80 -0
- package/dist/bot.test.js.map +1 -0
- package/dist/components/Layout.d.ts +26 -0
- package/dist/components/Layout.d.ts.map +1 -0
- package/dist/components/Layout.js +36 -0
- package/dist/components/Layout.js.map +1 -0
- package/dist/components/Message.d.ts +21 -0
- package/dist/components/Message.d.ts.map +1 -0
- package/dist/components/Message.js +99 -0
- package/dist/components/Message.js.map +1 -0
- package/dist/components/Message.test.d.ts +2 -0
- package/dist/components/Message.test.js +32 -0
- package/dist/components/Message.test.js.map +1 -0
- package/dist/deno.js +73 -0
- package/dist/deno.js.map +1 -0
- package/dist/emoji.d.ts +87 -0
- package/dist/emoji.d.ts.map +1 -0
- package/dist/emoji.js +37 -0
- package/dist/emoji.js.map +1 -0
- package/dist/emoji.test.d.ts +2 -0
- package/dist/emoji.test.js +109 -0
- package/dist/emoji.test.js.map +1 -0
- package/dist/events.d.ts +110 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +4 -0
- package/dist/follow-impl.d.ts +23 -0
- package/dist/follow-impl.d.ts.map +1 -0
- package/dist/follow-impl.js +51 -0
- package/dist/follow-impl.js.map +1 -0
- package/dist/follow-impl.test.d.ts +2 -0
- package/dist/follow-impl.test.js +110 -0
- package/dist/follow-impl.test.js.map +1 -0
- package/dist/follow.d.ts +44 -0
- package/dist/follow.d.ts.map +1 -0
- package/dist/follow.js +4 -0
- package/dist/message-impl.d.ts +54 -0
- package/dist/message-impl.d.ts.map +1 -0
- package/dist/message-impl.js +439 -0
- package/dist/message-impl.js.map +1 -0
- package/dist/message-impl.test.d.ts +2 -0
- package/dist/message-impl.test.js +519 -0
- package/dist/message-impl.test.js.map +1 -0
- package/dist/message.d.ts +223 -0
- package/dist/message.d.ts.map +1 -0
- package/dist/message.js +8 -0
- package/dist/mod.d.ts +13 -0
- package/dist/mod.js +13 -0
- package/dist/pages.d.ts +20 -0
- package/dist/pages.d.ts.map +1 -0
- package/dist/pages.js +361 -0
- package/dist/pages.js.map +1 -0
- package/dist/reaction.d.ts +90 -0
- package/dist/reaction.d.ts.map +1 -0
- package/dist/reaction.js +7 -0
- package/dist/repository.d.ts +323 -0
- package/dist/repository.d.ts.map +1 -0
- package/dist/repository.js +483 -0
- package/dist/repository.js.map +1 -0
- package/dist/repository.test.d.ts +2 -0
- package/dist/repository.test.js +336 -0
- package/dist/repository.test.js.map +1 -0
- package/dist/session-impl.d.ts +32 -0
- package/dist/session-impl.d.ts.map +1 -0
- package/dist/session-impl.js +195 -0
- package/dist/session-impl.js.map +1 -0
- package/dist/session-impl.test.d.ts +20 -0
- package/dist/session-impl.test.d.ts.map +1 -0
- package/dist/session-impl.test.js +464 -0
- package/dist/session-impl.test.js.map +1 -0
- package/dist/session.d.ts +139 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +4 -0
- package/dist/text.d.ts +391 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +640 -0
- package/dist/text.js.map +1 -0
- package/dist/text.test.d.ts +2 -0
- package/dist/text.test.js +473 -0
- package/dist/text.test.js.map +1 -0
- package/package.json +137 -0
package/dist/text.js
ADDED
|
@@ -0,0 +1,640 @@
|
|
|
1
|
+
|
|
2
|
+
import { Temporal, toTemporalInstant } from "@js-temporal/polyfill";
|
|
3
|
+
Date.prototype.toTemporalInstant = toTemporalInstant;
|
|
4
|
+
|
|
5
|
+
import { Hashtag } from "@fedify/fedify/vocab";
|
|
6
|
+
import { Emoji as Emoji$1, Link as Link$1, Mention as Mention$1, getActorHandle as getActorHandle$1, isActor as isActor$1 } from "@fedify/fedify";
|
|
7
|
+
import { encode } from "html-entities";
|
|
8
|
+
import { hashtag as hashtag$1 } from "@fedify/markdown-it-hashtag";
|
|
9
|
+
import { mention as mention$1, toFullHandle } from "@fedify/markdown-it-mention";
|
|
10
|
+
import MarkdownIt from "markdown-it";
|
|
11
|
+
|
|
12
|
+
//#region src/text.ts
|
|
13
|
+
/**
|
|
14
|
+
* Checks if a value is a {@link Text} tree.
|
|
15
|
+
* @param value The value to check.
|
|
16
|
+
* @returns `true` if the value is a {@link Text} tree, `false` otherwise.
|
|
17
|
+
* @typeParam TContextData The type of the context data.
|
|
18
|
+
*/
|
|
19
|
+
function isText(value) {
|
|
20
|
+
return typeof value === "object" && value !== null && "getHtml" in value && "getTags" in value && typeof value.getHtml === "function" && typeof value.getTags === "function" && "type" in value && (value.type === "block" || value.type === "inline");
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Checks if a given `actor` is mentioned in a `text`.
|
|
24
|
+
* @param session The bot session.
|
|
25
|
+
* @param text The text object to check.
|
|
26
|
+
* @param actor The actor to check. It can be either an `Actor` object or
|
|
27
|
+
* an actor URI.
|
|
28
|
+
* @returns `true` if the actor is mentioned in the text, `false` otherwise.
|
|
29
|
+
*/
|
|
30
|
+
async function mentions(session, text$1, actor) {
|
|
31
|
+
if (isActor$1(actor)) {
|
|
32
|
+
if (actor.id == null) return false;
|
|
33
|
+
actor = actor.id;
|
|
34
|
+
}
|
|
35
|
+
for await (const tag of text$1.getTags(session)) if (tag instanceof Mention$1 && tag.href?.href === actor.href) return true;
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* A text tree that renders a template string with values. You normally
|
|
40
|
+
* don't need to instantiate this directly; use the {@link text} function
|
|
41
|
+
* instead.
|
|
42
|
+
* @typeParam TContextData The type of the context data.
|
|
43
|
+
*/
|
|
44
|
+
var TemplatedText = class {
|
|
45
|
+
type = "block";
|
|
46
|
+
#strings;
|
|
47
|
+
#values;
|
|
48
|
+
/**
|
|
49
|
+
* Creates a text tree with a template string and values.
|
|
50
|
+
* @param strings The template strings.
|
|
51
|
+
* @param values The values to interpolate.
|
|
52
|
+
*/
|
|
53
|
+
constructor(strings, ...values) {
|
|
54
|
+
this.#strings = strings;
|
|
55
|
+
this.#values = values.map((v) => {
|
|
56
|
+
if (isText(v)) return v;
|
|
57
|
+
if (v instanceof URL) return link(v);
|
|
58
|
+
if (isActor$1(v)) return mention(v);
|
|
59
|
+
if (v instanceof Emoji$1) return customEmoji(v);
|
|
60
|
+
return new PlainText(String(v));
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
async *getHtml(session) {
|
|
64
|
+
let paraState = "closed";
|
|
65
|
+
for (let i = 0; i < this.#strings.length; i++) {
|
|
66
|
+
const paragraphs = this.#strings[i].split(/([ \t]*\r?\n){2,}/g);
|
|
67
|
+
let p = 0;
|
|
68
|
+
for (const para of paragraphs) {
|
|
69
|
+
if (p > 0 && paraState === "opened") {
|
|
70
|
+
yield "</p>";
|
|
71
|
+
paraState = "closed";
|
|
72
|
+
}
|
|
73
|
+
const lines = para.split("\n");
|
|
74
|
+
let l = 0;
|
|
75
|
+
for (const line of lines) {
|
|
76
|
+
if (line.trim() === "") continue;
|
|
77
|
+
if (l < 1 && paraState === "closed") {
|
|
78
|
+
yield "<p>";
|
|
79
|
+
paraState = "opened";
|
|
80
|
+
}
|
|
81
|
+
if (l > 0) yield "<br>";
|
|
82
|
+
yield encode(line);
|
|
83
|
+
l++;
|
|
84
|
+
}
|
|
85
|
+
p++;
|
|
86
|
+
}
|
|
87
|
+
if (i < this.#values.length) {
|
|
88
|
+
const value = this.#values[i];
|
|
89
|
+
if (value.type === "block" && paraState === "opened") {
|
|
90
|
+
yield "</p>";
|
|
91
|
+
paraState = "closed";
|
|
92
|
+
} else if (value.type === "inline" && paraState === "closed") {
|
|
93
|
+
yield "<p>";
|
|
94
|
+
paraState = "opened";
|
|
95
|
+
}
|
|
96
|
+
yield* value.getHtml(session);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (paraState === "opened") yield "</p>";
|
|
100
|
+
}
|
|
101
|
+
async *getTags(session) {
|
|
102
|
+
for (const value of this.#values) {
|
|
103
|
+
if (!isText(value)) continue;
|
|
104
|
+
yield* value.getTags(session);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
getCachedObjects() {
|
|
108
|
+
const objects = [];
|
|
109
|
+
for (const value of this.#values) {
|
|
110
|
+
if (!isText(value)) continue;
|
|
111
|
+
objects.push(...value.getCachedObjects());
|
|
112
|
+
}
|
|
113
|
+
return objects;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* A template string tag that creates a {@link Text} tree.
|
|
118
|
+
*
|
|
119
|
+
* Basically, it only interpolates values into the template string and
|
|
120
|
+
* escapes HTML characters, except for line breaks and paragraphs.
|
|
121
|
+
* For example, the below code:
|
|
122
|
+
*
|
|
123
|
+
* ```ts
|
|
124
|
+
* text`Hello, <${em("World")}>!\n\nGoodbye!`
|
|
125
|
+
* ```
|
|
126
|
+
*
|
|
127
|
+
* will be rendered as:
|
|
128
|
+
*
|
|
129
|
+
* ```html
|
|
130
|
+
* <p>Hello, <<em>World</em>>!</p>
|
|
131
|
+
* <p>Goodbye!</p>
|
|
132
|
+
* ```
|
|
133
|
+
*
|
|
134
|
+
* @typeParam TContextData The type of the context data.
|
|
135
|
+
* @param strings The template strings.
|
|
136
|
+
* @param values The values to interpolate.
|
|
137
|
+
* @returns A {@link Text} tree.
|
|
138
|
+
*/
|
|
139
|
+
function text(strings, ...values) {
|
|
140
|
+
return new TemplatedText(strings, ...values);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* A text tree that renders a plain text. You normally don't need to
|
|
144
|
+
* instantiate this directly; use the {@link plainText} function instead.
|
|
145
|
+
* @typeParam TContextData The type of the context data.
|
|
146
|
+
*/
|
|
147
|
+
var PlainText = class {
|
|
148
|
+
type = "inline";
|
|
149
|
+
text;
|
|
150
|
+
/**
|
|
151
|
+
* Creates a {@link PlainText} tree with a plain text.
|
|
152
|
+
* @param text The plain text.
|
|
153
|
+
*/
|
|
154
|
+
constructor(text$1) {
|
|
155
|
+
this.text = text$1;
|
|
156
|
+
}
|
|
157
|
+
async *getHtml(_session) {
|
|
158
|
+
let first = true;
|
|
159
|
+
for (const line of this.text.split("\n")) {
|
|
160
|
+
if (!first) yield "<br>";
|
|
161
|
+
yield encode(line);
|
|
162
|
+
first = false;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
async *getTags(_session) {}
|
|
166
|
+
getCachedObjects() {
|
|
167
|
+
return [];
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* A function that creates a {@link PlainText} tree. It only does two simple
|
|
172
|
+
* things:
|
|
173
|
+
*
|
|
174
|
+
* - Escaping the given text so that it can be safely rendered as HTML
|
|
175
|
+
* - Splitting the text by line breaks and rendering them as hard line breaks
|
|
176
|
+
* @typeParam TContextData The type of the context data.
|
|
177
|
+
* @param text The plain text.
|
|
178
|
+
* @returns A {@link PlainText} tree.
|
|
179
|
+
*/
|
|
180
|
+
function plainText(text$1) {
|
|
181
|
+
return new PlainText(text$1);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* A text tree that renders a mention. You normally don't need to
|
|
185
|
+
* instantiate this directly; use the {@link mention} function instead.
|
|
186
|
+
* @typeParam TContextData The type of the context data.
|
|
187
|
+
*/
|
|
188
|
+
var MentionText = class {
|
|
189
|
+
type = "inline";
|
|
190
|
+
#label;
|
|
191
|
+
#actor;
|
|
192
|
+
#cachedObject;
|
|
193
|
+
#labelPromise;
|
|
194
|
+
#actorPromise;
|
|
195
|
+
/**
|
|
196
|
+
* Creates a {@link MentionText} tree with a label and an actor.
|
|
197
|
+
* @param label The label of the mention.
|
|
198
|
+
* @param actor The actor which the mention refers to.
|
|
199
|
+
*/
|
|
200
|
+
constructor(label, actor) {
|
|
201
|
+
this.#label = label;
|
|
202
|
+
this.#actor = actor;
|
|
203
|
+
if (isActor$1(actor)) this.#cachedObject = actor;
|
|
204
|
+
}
|
|
205
|
+
#getLabel(session) {
|
|
206
|
+
if (typeof this.#label === "string") return Promise.resolve(this.#label);
|
|
207
|
+
if (this.#labelPromise != null) return this.#labelPromise;
|
|
208
|
+
return this.#labelPromise = this.#label(session);
|
|
209
|
+
}
|
|
210
|
+
#getActor(session) {
|
|
211
|
+
if (isActor$1(this.#actor)) return Promise.resolve(this.#actor);
|
|
212
|
+
if (this.#actorPromise != null) return this.#actorPromise;
|
|
213
|
+
return this.#actorPromise = this.#actor(session).then((actor) => {
|
|
214
|
+
if (actor != null) this.#cachedObject = actor;
|
|
215
|
+
return actor;
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
async *getHtml(session) {
|
|
219
|
+
const label = await this.#getLabel(session);
|
|
220
|
+
const actor = await this.#getActor(session);
|
|
221
|
+
const url = !isActor$1(actor) ? null : actor.url == null ? actor.id : actor.url instanceof Link$1 ? actor.url.href : actor.url;
|
|
222
|
+
if (url == null) {
|
|
223
|
+
yield encode(label);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
yield "<a href=\"";
|
|
227
|
+
yield encode(url.href);
|
|
228
|
+
yield "\" translate=\"no\" class=\"h-card u-url mention\" target=\"_blank\">";
|
|
229
|
+
if (label.startsWith("@")) {
|
|
230
|
+
yield "@<span>";
|
|
231
|
+
yield encode(label.substring(1));
|
|
232
|
+
yield "</span>";
|
|
233
|
+
} else yield encode(label);
|
|
234
|
+
yield "</a>";
|
|
235
|
+
}
|
|
236
|
+
async *getTags(session) {
|
|
237
|
+
const label = await this.#getLabel(session);
|
|
238
|
+
const actor = await this.#getActor(session);
|
|
239
|
+
if (isActor$1(actor)) yield new Mention$1({
|
|
240
|
+
name: label,
|
|
241
|
+
href: actor.id
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
getCachedObjects() {
|
|
245
|
+
return this.#cachedObject == null ? [] : [this.#cachedObject];
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
function mention(a, b) {
|
|
249
|
+
if (b != null) return new MentionText(a, isActor$1(b) ? b : async (session) => {
|
|
250
|
+
if (session.actorId.href === b.href) return await session.getActor();
|
|
251
|
+
const documentLoader = await session.context.getDocumentLoader(session.bot);
|
|
252
|
+
return await session.context.lookupObject(b, { documentLoader });
|
|
253
|
+
});
|
|
254
|
+
else if (typeof a === "string") return new MentionText(a, async (session) => {
|
|
255
|
+
if (session.actorHandle === a) return await session.getActor();
|
|
256
|
+
const documentLoader = await session.context.getDocumentLoader(session.bot);
|
|
257
|
+
return await session.context.lookupObject(a, { documentLoader });
|
|
258
|
+
});
|
|
259
|
+
else if (isActor$1(a)) return new MentionText((session) => a.id?.href === session.actorId.href ? Promise.resolve(session.actorHandle) : getActorHandle$1(a, session.context), a);
|
|
260
|
+
return new MentionText((session) => a.href === session.actorId.href ? Promise.resolve(session.actorHandle) : getActorHandle$1(a, session.context), async (session) => {
|
|
261
|
+
if (a.href === session.actorId.href) return await session.getActor();
|
|
262
|
+
const documentLoader = await session.context.getDocumentLoader(session.bot);
|
|
263
|
+
return await session.context.lookupObject(a, { documentLoader });
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* A text tree that renders a hashtag. You normally don't need to
|
|
268
|
+
* instantiate this directly; use the {@link hashtag} function instead.
|
|
269
|
+
* @typeParam TContextData The type of the context data.
|
|
270
|
+
*/
|
|
271
|
+
var HashtagText = class {
|
|
272
|
+
type = "inline";
|
|
273
|
+
#tag;
|
|
274
|
+
/**
|
|
275
|
+
* Creates a {@link HashtagText} tree with a tag.
|
|
276
|
+
* @param tag The hashtag. It does not matter whether it starts with `"#"`.
|
|
277
|
+
*/
|
|
278
|
+
constructor(tag) {
|
|
279
|
+
this.#tag = tag.trimStart().replace(/^#/, "").trim().replace(/\s+/g, " ");
|
|
280
|
+
}
|
|
281
|
+
async *getHtml(session) {
|
|
282
|
+
yield "<a href=\"";
|
|
283
|
+
yield encode(session.context.origin);
|
|
284
|
+
yield "/tags/";
|
|
285
|
+
yield encode(encodeURIComponent(this.#tag.toLowerCase()));
|
|
286
|
+
yield "\" class=\"mention hashtag\" rel=\"tag\" target=\"_blank\">#<span>";
|
|
287
|
+
yield this.#tag;
|
|
288
|
+
yield "</span></a>";
|
|
289
|
+
}
|
|
290
|
+
async *getTags(session) {
|
|
291
|
+
yield new Hashtag({
|
|
292
|
+
href: new URL(`/tags/${encodeURIComponent(this.#tag.toLowerCase())}`, session.context.origin),
|
|
293
|
+
name: `#${this.#tag.toLowerCase()}`
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
getCachedObjects() {
|
|
297
|
+
return [];
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
/**
|
|
301
|
+
* Creates a hashtag. You can use this function to create a {@link HashtagText}
|
|
302
|
+
* tree.
|
|
303
|
+
* @param tag The hashtag. It does not matter whether it starts with `"#"`.
|
|
304
|
+
* @returns A {@link HashtagText} tree.
|
|
305
|
+
*/
|
|
306
|
+
function hashtag(tag) {
|
|
307
|
+
return new HashtagText(tag);
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* A text tree that renders a `<strong>` text. You normally don't need to
|
|
311
|
+
* instantiate this directly; use the {@link strong} function instead.
|
|
312
|
+
* @typeParam TContextData The type of the context data.
|
|
313
|
+
*/
|
|
314
|
+
var StrongText = class {
|
|
315
|
+
type = "inline";
|
|
316
|
+
#text;
|
|
317
|
+
/**
|
|
318
|
+
* Creates a {@link StrongText} tree with a text.
|
|
319
|
+
* @param text The text to render as `<strong>`.
|
|
320
|
+
*/
|
|
321
|
+
constructor(text$1) {
|
|
322
|
+
this.#text = typeof text$1 === "string" ? new PlainText(text$1) : text$1;
|
|
323
|
+
}
|
|
324
|
+
async *getHtml(session) {
|
|
325
|
+
yield "<strong>";
|
|
326
|
+
yield* this.#text.getHtml(session);
|
|
327
|
+
yield "</strong>";
|
|
328
|
+
}
|
|
329
|
+
getTags(session) {
|
|
330
|
+
return this.#text.getTags(session);
|
|
331
|
+
}
|
|
332
|
+
getCachedObjects() {
|
|
333
|
+
return [];
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
/**
|
|
337
|
+
* Applies `<strong>` tag to a text. You can use this function to create a
|
|
338
|
+
* {@link StrongText} tree.
|
|
339
|
+
* @typeParam TContextData The type of the context data.
|
|
340
|
+
* @param text The text to render as `<strong>`. It can be a plain text or
|
|
341
|
+
* another text tree.
|
|
342
|
+
* @returns A {@link StrongText} tree.
|
|
343
|
+
*/
|
|
344
|
+
function strong(text$1) {
|
|
345
|
+
return new StrongText(text$1);
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* A text tree that renders an `<em>` text. You normally don't need to
|
|
349
|
+
* instantiate this directly; use the {@link em} function instead.
|
|
350
|
+
* @typeParam TContextData The type of the context data.
|
|
351
|
+
*/
|
|
352
|
+
var EmText = class {
|
|
353
|
+
type = "inline";
|
|
354
|
+
#text;
|
|
355
|
+
constructor(text$1) {
|
|
356
|
+
this.#text = typeof text$1 === "string" ? new PlainText(text$1) : text$1;
|
|
357
|
+
}
|
|
358
|
+
async *getHtml(session) {
|
|
359
|
+
yield "<em>";
|
|
360
|
+
yield* this.#text.getHtml(session);
|
|
361
|
+
yield "</em>";
|
|
362
|
+
}
|
|
363
|
+
getTags(session) {
|
|
364
|
+
return this.#text.getTags(session);
|
|
365
|
+
}
|
|
366
|
+
getCachedObjects() {
|
|
367
|
+
return [];
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
/**
|
|
371
|
+
* Applies `<em>` tag to a text. You can use this function to create an
|
|
372
|
+
* {@link EmText} tree.
|
|
373
|
+
* @typeParam TContextData The type of the context data.
|
|
374
|
+
* @param text The text to render as `<em>`. It can be a plain text or
|
|
375
|
+
* another text tree.
|
|
376
|
+
* @returns A {@link EmText} tree.
|
|
377
|
+
*/
|
|
378
|
+
function em(text$1) {
|
|
379
|
+
return new EmText(text$1);
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* A text tree that renders a link. You normally don't need to instantiate
|
|
383
|
+
* this directly; use the {@link link} function instead.
|
|
384
|
+
* @typeParam TContextData The type of the context data.
|
|
385
|
+
*/
|
|
386
|
+
var LinkText = class {
|
|
387
|
+
type = "inline";
|
|
388
|
+
#label;
|
|
389
|
+
#href;
|
|
390
|
+
/**
|
|
391
|
+
* Creates a {@link LinkText} tree with a label and a URL.
|
|
392
|
+
* @param label The label of the link.
|
|
393
|
+
* @param href The URL of the link. It has to be an absolute URL.
|
|
394
|
+
*/
|
|
395
|
+
constructor(label, href) {
|
|
396
|
+
this.#label = typeof label === "string" ? new PlainText(label) : label;
|
|
397
|
+
this.#href = typeof href === "string" ? new URL(href) : href;
|
|
398
|
+
}
|
|
399
|
+
async *getHtml(session) {
|
|
400
|
+
yield "<a href=\"";
|
|
401
|
+
yield encode(this.#href.href);
|
|
402
|
+
yield "\" target=\"_blank\">";
|
|
403
|
+
yield* this.#label.getHtml(session);
|
|
404
|
+
yield "</a>";
|
|
405
|
+
}
|
|
406
|
+
getTags(session) {
|
|
407
|
+
return this.#label.getTags(session);
|
|
408
|
+
}
|
|
409
|
+
getCachedObjects() {
|
|
410
|
+
return this.#label.getCachedObjects();
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
function link(label, href) {
|
|
414
|
+
return href == null ? new LinkText(String(label), label) : new LinkText(isText(label) ? label : label.toString(), href);
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* A text tree that renders a inline code. You normally don't need to
|
|
418
|
+
* instantiate this directly; use the {@link code} function instead.
|
|
419
|
+
* @typeParam TContextData The type of the context data.
|
|
420
|
+
*/
|
|
421
|
+
var CodeText = class {
|
|
422
|
+
type = "inline";
|
|
423
|
+
#code;
|
|
424
|
+
/**
|
|
425
|
+
* Creates a {@link CodeText} tree with a code.
|
|
426
|
+
* @param code The code to render.
|
|
427
|
+
*/
|
|
428
|
+
constructor(code$1) {
|
|
429
|
+
this.#code = typeof code$1 === "string" ? new PlainText(code$1) : code$1;
|
|
430
|
+
}
|
|
431
|
+
async *getHtml(session) {
|
|
432
|
+
yield "<code>";
|
|
433
|
+
yield* this.#code.getHtml(session);
|
|
434
|
+
yield "</code>";
|
|
435
|
+
}
|
|
436
|
+
getTags(session) {
|
|
437
|
+
return this.#code.getTags(session);
|
|
438
|
+
}
|
|
439
|
+
getCachedObjects() {
|
|
440
|
+
return [];
|
|
441
|
+
}
|
|
442
|
+
};
|
|
443
|
+
/**
|
|
444
|
+
* Applies `<code>` tag to a text. You can use this function to create
|
|
445
|
+
* a {@link CodeText} tree.
|
|
446
|
+
* @param code The code to render.
|
|
447
|
+
* @returns A {@link CodeText} tree.
|
|
448
|
+
*/
|
|
449
|
+
function code(code$1) {
|
|
450
|
+
return new CodeText(code$1);
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* A text tree that renders a custom emoji. You normally don't need to
|
|
454
|
+
* instantiate this directly; use the {@link customEmoji} function instead.
|
|
455
|
+
* @typeParam TContextData The type of the context data.
|
|
456
|
+
* @since 0.2.0
|
|
457
|
+
*/
|
|
458
|
+
var CustomEmojiText = class {
|
|
459
|
+
type = "inline";
|
|
460
|
+
#emoji;
|
|
461
|
+
/**
|
|
462
|
+
* Creates a {@link CustomEmojiText} tree with a custom emoji.
|
|
463
|
+
* @param emoji The custom emoji to render.
|
|
464
|
+
*/
|
|
465
|
+
constructor(emoji) {
|
|
466
|
+
this.#emoji = emoji;
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Gets the emoji object. If the emoji is a deferred emoji, it will
|
|
470
|
+
* be resolved with the given session.
|
|
471
|
+
* @param session The bot session.
|
|
472
|
+
* @returns The emoji object.
|
|
473
|
+
*/
|
|
474
|
+
getEmoji(session) {
|
|
475
|
+
if (typeof this.#emoji === "function") return this.#emoji(session);
|
|
476
|
+
return this.#emoji;
|
|
477
|
+
}
|
|
478
|
+
async *getHtml(session) {
|
|
479
|
+
const emoji = this.getEmoji(session);
|
|
480
|
+
if (emoji.name == null) return;
|
|
481
|
+
yield "";
|
|
482
|
+
yield encode(emoji.name.toString());
|
|
483
|
+
yield "";
|
|
484
|
+
}
|
|
485
|
+
async *getTags(session) {
|
|
486
|
+
yield this.getEmoji(session);
|
|
487
|
+
}
|
|
488
|
+
getCachedObjects() {
|
|
489
|
+
return [];
|
|
490
|
+
}
|
|
491
|
+
};
|
|
492
|
+
/**
|
|
493
|
+
* Renders a custom emoji. You can use this function to create a
|
|
494
|
+
* {@link CustomEmojiText} tree.
|
|
495
|
+
* @param emoji The custom emoji to render. See also {@link Bot.addCustomEmojis}
|
|
496
|
+
* method.
|
|
497
|
+
* @returns A {@link CustomEmojiText} tree.
|
|
498
|
+
* @since 0.2.0
|
|
499
|
+
*/
|
|
500
|
+
function customEmoji(emoji) {
|
|
501
|
+
return new CustomEmojiText(emoji);
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* A text tree that renders a Markdown text. You normally don't need to
|
|
505
|
+
* instantiate this directly; use the {@link markdown} function instead.
|
|
506
|
+
*/
|
|
507
|
+
var MarkdownText = class {
|
|
508
|
+
type = "block";
|
|
509
|
+
#content;
|
|
510
|
+
#markdownIt;
|
|
511
|
+
#mentions;
|
|
512
|
+
#hashtags;
|
|
513
|
+
#actors;
|
|
514
|
+
/**
|
|
515
|
+
* Creates a {@link MarkdownText} tree with a Markdown content.
|
|
516
|
+
* @param content The Markdown content.
|
|
517
|
+
* @param options The options for rendering the Markdown content.
|
|
518
|
+
*/
|
|
519
|
+
constructor(content, options = {}) {
|
|
520
|
+
this.#content = content;
|
|
521
|
+
const md = MarkdownIt({
|
|
522
|
+
html: false,
|
|
523
|
+
linkify: options.linkify ?? true
|
|
524
|
+
});
|
|
525
|
+
if (options.mentions ?? true) {
|
|
526
|
+
md.use(mention$1, {
|
|
527
|
+
link(handle, env$1) {
|
|
528
|
+
if (env$1.actors == null) return `acct:${handle}`;
|
|
529
|
+
return env$1.actors[handle] ?? null;
|
|
530
|
+
},
|
|
531
|
+
linkAttributes(_handle, _env) {
|
|
532
|
+
return {
|
|
533
|
+
translate: "no",
|
|
534
|
+
class: "h-card u-url mention",
|
|
535
|
+
target: "_blank"
|
|
536
|
+
};
|
|
537
|
+
},
|
|
538
|
+
label: toFullHandle
|
|
539
|
+
});
|
|
540
|
+
const env = {
|
|
541
|
+
mentions: [],
|
|
542
|
+
hashtags: [],
|
|
543
|
+
origin: "http://localhost"
|
|
544
|
+
};
|
|
545
|
+
md.render(content, env);
|
|
546
|
+
this.#mentions = env.mentions;
|
|
547
|
+
}
|
|
548
|
+
if (options.hashtags ?? true) {
|
|
549
|
+
md.use(hashtag$1, {
|
|
550
|
+
link(hashtag$2, env$1) {
|
|
551
|
+
const tag = hashtag$2.substring(1).toLowerCase();
|
|
552
|
+
return new URL(`/tags/${encodeURIComponent(tag)}`, env$1.origin).href;
|
|
553
|
+
},
|
|
554
|
+
linkAttributes(_hashtag, _env) {
|
|
555
|
+
return {
|
|
556
|
+
class: "mention hashtag",
|
|
557
|
+
rel: "tag",
|
|
558
|
+
target: "_blank"
|
|
559
|
+
};
|
|
560
|
+
},
|
|
561
|
+
label(hashtag$2, _env) {
|
|
562
|
+
const tag = hashtag$2.substring(1);
|
|
563
|
+
return `#<span>${tag}</span>`;
|
|
564
|
+
}
|
|
565
|
+
});
|
|
566
|
+
const env = {
|
|
567
|
+
mentions: [],
|
|
568
|
+
hashtags: [],
|
|
569
|
+
origin: "http://localhost"
|
|
570
|
+
};
|
|
571
|
+
md.render(content, env);
|
|
572
|
+
this.#hashtags = env.hashtags;
|
|
573
|
+
}
|
|
574
|
+
this.#markdownIt = md;
|
|
575
|
+
}
|
|
576
|
+
async #getMentionedActors(session) {
|
|
577
|
+
if (this.#mentions == null) return {};
|
|
578
|
+
if (this.#actors != null) return this.#actors;
|
|
579
|
+
const documentLoader = await session.context.getDocumentLoader(session.bot);
|
|
580
|
+
const objects = await Promise.all(this.#mentions.map((m) => m === session.actorHandle ? session.getActor() : session.context.lookupObject(m, { documentLoader })));
|
|
581
|
+
const actors = {};
|
|
582
|
+
for (let i = 0; i < this.#mentions.length; i++) {
|
|
583
|
+
const object = objects[i];
|
|
584
|
+
if (object != null) actors[this.#mentions[i]] = object;
|
|
585
|
+
}
|
|
586
|
+
this.#actors = actors;
|
|
587
|
+
return actors;
|
|
588
|
+
}
|
|
589
|
+
async *getHtml(session) {
|
|
590
|
+
if (this.#mentions == null) {
|
|
591
|
+
yield this.#markdownIt.render(this.#content);
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
const actors = globalThis.Object.fromEntries(globalThis.Object.entries(await this.#getMentionedActors(session)).filter(([_, obj]) => isActor$1(obj)).map(([handle, actor]) => [handle, (actor.url instanceof Link$1 ? actor.url.href?.href : actor.url?.href) ?? actor.id?.href ?? null]).filter(([_, url]) => url != null));
|
|
595
|
+
const env = {
|
|
596
|
+
mentions: [],
|
|
597
|
+
hashtags: [],
|
|
598
|
+
origin: session.context.origin,
|
|
599
|
+
actors
|
|
600
|
+
};
|
|
601
|
+
yield this.#markdownIt.render(this.#content, env);
|
|
602
|
+
}
|
|
603
|
+
async *getTags(session) {
|
|
604
|
+
if (this.#mentions == null) return;
|
|
605
|
+
const actors = await this.#getMentionedActors(session);
|
|
606
|
+
for (const [handle, object] of globalThis.Object.entries(actors)) {
|
|
607
|
+
if (!isActor$1(object) || object.id == null) continue;
|
|
608
|
+
yield new Mention$1({
|
|
609
|
+
name: handle,
|
|
610
|
+
href: object.id
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
if (this.#hashtags != null) for (const hashtag$2 of this.#hashtags) {
|
|
614
|
+
const tag = hashtag$2.substring(1).toLowerCase();
|
|
615
|
+
yield new Hashtag({
|
|
616
|
+
name: `#${tag}`,
|
|
617
|
+
href: new URL(`/tags/${encodeURIComponent(tag)}`, session.context.origin)
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
getCachedObjects() {
|
|
622
|
+
return this.#actors == null ? [] : globalThis.Object.values(this.#actors);
|
|
623
|
+
}
|
|
624
|
+
};
|
|
625
|
+
/**
|
|
626
|
+
* Renders a Markdown text. You can use this function to create
|
|
627
|
+
* a {@link MarkdownText} tree. The mentions in the Markdown text
|
|
628
|
+
* will be rendered as links unless the `mentions` option is set to
|
|
629
|
+
* `false`.
|
|
630
|
+
* @param content The Markdown content.
|
|
631
|
+
* @param options The options for rendering the Markdown content.
|
|
632
|
+
* @returns A {@link MarkdownText} tree.
|
|
633
|
+
*/
|
|
634
|
+
function markdown(content, options = {}) {
|
|
635
|
+
return new MarkdownText(content, options);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
//#endregion
|
|
639
|
+
export { CodeText, CustomEmojiText, EmText, HashtagText, LinkText, MarkdownText, MentionText, PlainText, StrongText, TemplatedText, code, customEmoji, em, hashtag, isText, link, markdown, mention, mentions, plainText, strong, text };
|
|
640
|
+
//# sourceMappingURL=text.js.map
|