@fedify/botkit 0.5.0-dev.209 → 0.5.0-dev.225
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/bot-group.test.d.ts +2 -0
- package/dist/bot-group.test.js +220 -0
- package/dist/bot-group.test.js.map +1 -0
- package/dist/bot-impl.d.ts +132 -13
- package/dist/bot-impl.d.ts.map +1 -1
- package/dist/bot-impl.js +400 -178
- package/dist/bot-impl.js.map +1 -1
- package/dist/bot-impl.test.js +214 -76
- package/dist/bot-impl.test.js.map +1 -1
- package/dist/bot.d.ts +94 -48
- package/dist/bot.d.ts.map +1 -1
- package/dist/bot.js +2 -104
- package/dist/bot.js.map +1 -1
- package/dist/bot.test.js +59 -0
- package/dist/bot.test.js.map +1 -1
- package/dist/components/FollowButton.d.ts +5 -3
- package/dist/components/FollowButton.d.ts.map +1 -1
- package/dist/components/FollowButton.js +2 -2
- package/dist/components/FollowButton.js.map +1 -1
- package/dist/components/Follower.d.ts +2 -2
- package/dist/components/Layout.js +1 -1
- package/dist/components/Layout.js.map +1 -1
- package/dist/components/Message.d.ts +2 -2
- package/dist/deno.js +2 -1
- package/dist/deno.js.map +1 -1
- package/dist/follow-impl.test.js +3 -3
- package/dist/follow-impl.test.js.map +1 -1
- package/dist/instance-impl.d.ts +158 -0
- package/dist/instance-impl.d.ts.map +1 -0
- package/dist/instance-impl.js +603 -0
- package/dist/instance-impl.js.map +1 -0
- package/dist/instance-impl.test.d.ts +2 -0
- package/dist/instance-impl.test.js +103 -0
- package/dist/instance-impl.test.js.map +1 -0
- package/dist/instance-multi.test.d.ts +2 -0
- package/dist/instance-multi.test.js +151 -0
- package/dist/instance-multi.test.js.map +1 -0
- package/dist/instance-routing.test.d.ts +2 -0
- package/dist/instance-routing.test.js +367 -0
- package/dist/instance-routing.test.js.map +1 -0
- package/dist/instance.d.ts +318 -0
- package/dist/instance.d.ts.map +1 -0
- package/dist/instance.js +51 -0
- package/dist/instance.js.map +1 -0
- package/dist/message-impl.d.ts.map +1 -1
- package/dist/message-impl.js +17 -10
- package/dist/message-impl.js.map +1 -1
- package/dist/message-impl.test.js +43 -9
- package/dist/message-impl.test.js.map +1 -1
- package/dist/mod.d.ts +5 -3
- package/dist/mod.js +4 -2
- package/dist/pages.d.ts +10 -1
- package/dist/pages.d.ts.map +1 -1
- package/dist/pages.js +112 -41
- package/dist/pages.js.map +1 -1
- package/dist/pages.test.d.ts +2 -0
- package/dist/pages.test.js +170 -0
- package/dist/pages.test.js.map +1 -0
- package/dist/repository.d.ts +385 -138
- package/dist/repository.d.ts.map +1 -1
- package/dist/repository.js +595 -223
- package/dist/repository.js.map +1 -1
- package/dist/repository.test.js +564 -136
- package/dist/repository.test.js.map +1 -1
- package/dist/session-impl.d.ts.map +1 -1
- package/dist/session-impl.js +13 -4
- 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 -9
- package/dist/session-impl.test.js.map +1 -1
- package/dist/session.d.ts +8 -3
- package/dist/session.d.ts.map +1 -1
- package/dist/text.d.ts.map +1 -1
- package/dist/text.js +27 -10
- package/dist/text.js.map +1 -1
- package/dist/text.test.js +37 -2
- package/dist/text.test.js.map +1 -1
- package/dist/uri.d.ts +46 -0
- package/dist/uri.d.ts.map +1 -0
- package/dist/uri.js +64 -0
- package/dist/uri.js.map +1 -0
- package/dist/uri.test.d.ts +2 -0
- package/dist/uri.test.js +93 -0
- package/dist/uri.test.js.map +1 -0
- package/package.json +5 -1
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
|
|
2
|
+
import { Temporal, toTemporalInstant } from "@js-temporal/polyfill";
|
|
3
|
+
Date.prototype.toTemporalInstant = toTemporalInstant;
|
|
4
|
+
|
|
5
|
+
import { MemoryRepository } from "./repository.js";
|
|
6
|
+
import { BotImpl } from "./bot-impl.js";
|
|
7
|
+
import { InstanceImpl } from "./instance-impl.js";
|
|
8
|
+
import { MemoryKvStore } from "@fedify/fedify/federation";
|
|
9
|
+
import { Create, Note, PUBLIC_COLLECTION } from "@fedify/vocab";
|
|
10
|
+
import assert from "node:assert";
|
|
11
|
+
import { describe, test } from "node:test";
|
|
12
|
+
|
|
13
|
+
//#region src/pages.test.ts
|
|
14
|
+
const messageId = "01941f29-7c00-7fe8-ab0a-7b593990a3c0";
|
|
15
|
+
async function seedMessage(repository, identifier) {
|
|
16
|
+
await repository.addMessage(identifier, messageId, new Create({
|
|
17
|
+
id: new URL(`https://example.com/ap/actor/${identifier}/create/${messageId}`),
|
|
18
|
+
actor: new URL(`https://example.com/ap/actor/${identifier}`),
|
|
19
|
+
to: PUBLIC_COLLECTION,
|
|
20
|
+
object: new Note({
|
|
21
|
+
id: new URL(`https://example.com/ap/actor/${identifier}/note/${messageId}`),
|
|
22
|
+
attribution: new URL(`https://example.com/ap/actor/${identifier}`),
|
|
23
|
+
to: PUBLIC_COLLECTION,
|
|
24
|
+
content: "Hello, world!",
|
|
25
|
+
published: Temporal.Instant.from("2025-01-01T00:00:00Z")
|
|
26
|
+
}),
|
|
27
|
+
published: Temporal.Instant.from("2025-01-01T00:00:00Z")
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
describe("single-bot web pages", () => {
|
|
31
|
+
test("serve the bot at the web root", async () => {
|
|
32
|
+
const repository = new MemoryRepository();
|
|
33
|
+
const bot = new BotImpl({
|
|
34
|
+
kv: new MemoryKvStore(),
|
|
35
|
+
repository,
|
|
36
|
+
username: "mybot",
|
|
37
|
+
name: "My Bot"
|
|
38
|
+
});
|
|
39
|
+
await seedMessage(repository, "bot");
|
|
40
|
+
const profile = await bot.fetch(new Request("https://example.com/"), void 0);
|
|
41
|
+
assert.deepStrictEqual(profile.status, 200);
|
|
42
|
+
const html = await profile.text();
|
|
43
|
+
assert.ok(html.includes("@mybot@example.com"));
|
|
44
|
+
assert.ok(html.includes("action=\"/follow\""));
|
|
45
|
+
const message = await bot.fetch(new Request(`https://example.com/message/${messageId}`), void 0);
|
|
46
|
+
assert.deepStrictEqual(message.status, 200);
|
|
47
|
+
const feed = await bot.fetch(new Request("https://example.com/feed.xml"), void 0);
|
|
48
|
+
assert.deepStrictEqual(feed.status, 200);
|
|
49
|
+
assert.ok(feed.headers.get("Content-Type")?.startsWith("application/atom+xml"));
|
|
50
|
+
});
|
|
51
|
+
test("use root-relative web URLs", () => {
|
|
52
|
+
const bot = new BotImpl({
|
|
53
|
+
kv: new MemoryKvStore(),
|
|
54
|
+
username: "mybot"
|
|
55
|
+
});
|
|
56
|
+
assert.deepStrictEqual(bot.instance.getBotWebUrl(bot, "https://example.com").href, "https://example.com/");
|
|
57
|
+
assert.deepStrictEqual(bot.instance.getMessageWebUrl(bot, messageId, "https://example.com").href, `https://example.com/message/${messageId}`);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
describe("multi-bot web pages", () => {
|
|
61
|
+
function createInstanceWithBots() {
|
|
62
|
+
const repository = new MemoryRepository();
|
|
63
|
+
const instance = new InstanceImpl({
|
|
64
|
+
kv: new MemoryKvStore(),
|
|
65
|
+
repository
|
|
66
|
+
});
|
|
67
|
+
instance.createBot("alpha", {
|
|
68
|
+
username: "alphabot",
|
|
69
|
+
name: "Alpha"
|
|
70
|
+
});
|
|
71
|
+
instance.createBot("beta", {
|
|
72
|
+
username: "betabot",
|
|
73
|
+
name: "Beta"
|
|
74
|
+
});
|
|
75
|
+
return {
|
|
76
|
+
instance,
|
|
77
|
+
repository
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
test("list the hosted bots at the web root", async () => {
|
|
81
|
+
const { instance } = createInstanceWithBots();
|
|
82
|
+
const response = await instance.fetch(new Request("https://example.com/"), void 0);
|
|
83
|
+
assert.deepStrictEqual(response.status, 200);
|
|
84
|
+
const html = await response.text();
|
|
85
|
+
assert.ok(html.includes("@alphabot@example.com"));
|
|
86
|
+
assert.ok(html.includes("@betabot@example.com"));
|
|
87
|
+
assert.ok(html.includes("href=\"/@alphabot\""));
|
|
88
|
+
});
|
|
89
|
+
test("serve per-bot profiles under /@{username}", async () => {
|
|
90
|
+
const { instance } = createInstanceWithBots();
|
|
91
|
+
const response = await instance.fetch(new Request("https://example.com/@alphabot"), void 0);
|
|
92
|
+
assert.deepStrictEqual(response.status, 200);
|
|
93
|
+
const html = await response.text();
|
|
94
|
+
assert.ok(html.includes("@alphabot@example.com"));
|
|
95
|
+
assert.ok(html.includes("action=\"/@alphabot/follow\""));
|
|
96
|
+
assert.ok(!html.includes("@betabot@example.com"));
|
|
97
|
+
const unknown = await instance.fetch(new Request("https://example.com/@nobody"), void 0);
|
|
98
|
+
assert.deepStrictEqual(unknown.status, 404);
|
|
99
|
+
});
|
|
100
|
+
test("serve per-bot message permalinks and feeds", async () => {
|
|
101
|
+
const { instance, repository } = createInstanceWithBots();
|
|
102
|
+
await seedMessage(repository, "alpha");
|
|
103
|
+
const message = await instance.fetch(new Request(`https://example.com/@alphabot/${messageId}`), void 0);
|
|
104
|
+
assert.deepStrictEqual(message.status, 200);
|
|
105
|
+
const cross = await instance.fetch(new Request(`https://example.com/@betabot/${messageId}`), void 0);
|
|
106
|
+
assert.deepStrictEqual(cross.status, 404);
|
|
107
|
+
const feed = await instance.fetch(new Request("https://example.com/@alphabot/feed.xml"), void 0);
|
|
108
|
+
assert.deepStrictEqual(feed.status, 200);
|
|
109
|
+
assert.ok(feed.headers.get("Content-Type")?.startsWith("application/atom+xml"));
|
|
110
|
+
const followers = await instance.fetch(new Request("https://example.com/@alphabot/followers"), void 0);
|
|
111
|
+
assert.deepStrictEqual(followers.status, 200);
|
|
112
|
+
});
|
|
113
|
+
test("use username-based web URLs", () => {
|
|
114
|
+
const { instance } = createInstanceWithBots();
|
|
115
|
+
const alpha = instance.getBot("alpha");
|
|
116
|
+
assert.deepStrictEqual(instance.getBotWebUrl(alpha, "https://example.com").href, "https://example.com/@alphabot");
|
|
117
|
+
assert.deepStrictEqual(instance.getMessageWebUrl(alpha, messageId, "https://example.com").href, `https://example.com/@alphabot/${messageId}`);
|
|
118
|
+
});
|
|
119
|
+
test("advertise the web URL on the actor", async () => {
|
|
120
|
+
const { instance } = createInstanceWithBots();
|
|
121
|
+
const response = await instance.fetch(new Request("https://example.com/ap/actor/alpha", { headers: { Accept: "application/activity+json" } }), void 0);
|
|
122
|
+
assert.deepStrictEqual(response.status, 200);
|
|
123
|
+
const actor = await response.json();
|
|
124
|
+
assert.deepStrictEqual(actor.url, "https://example.com/@alphabot");
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
describe("usernames requiring percent-encoding", () => {
|
|
128
|
+
test("keep web paths and routes consistent", async () => {
|
|
129
|
+
const instance = new InstanceImpl({
|
|
130
|
+
kv: new MemoryKvStore(),
|
|
131
|
+
repository: new MemoryRepository()
|
|
132
|
+
});
|
|
133
|
+
instance.createBot("alpha", { username: "weird+bot" });
|
|
134
|
+
instance.createBot("beta", { username: "betabot" });
|
|
135
|
+
const alpha = instance.getBot("alpha");
|
|
136
|
+
const url = instance.getBotWebUrl(alpha, "https://example.com");
|
|
137
|
+
assert.deepStrictEqual(url.href, "https://example.com/@weird%2Bbot");
|
|
138
|
+
const response = await instance.fetch(new Request(url), void 0);
|
|
139
|
+
assert.deepStrictEqual(response.status, 200);
|
|
140
|
+
const html = await response.text();
|
|
141
|
+
assert.ok(html.includes("weird+bot"));
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
describe("custom CSS", () => {
|
|
145
|
+
const css = "main > p { color: red; }";
|
|
146
|
+
test("is not HTML-escaped on single-bot pages", async () => {
|
|
147
|
+
const bot = new BotImpl({
|
|
148
|
+
kv: new MemoryKvStore(),
|
|
149
|
+
username: "mybot",
|
|
150
|
+
pages: { css }
|
|
151
|
+
});
|
|
152
|
+
const response = await bot.fetch(new Request("https://example.com/"), void 0);
|
|
153
|
+
const html = await response.text();
|
|
154
|
+
assert.ok(html.includes(css));
|
|
155
|
+
});
|
|
156
|
+
test("is not HTML-escaped on the instance index", async () => {
|
|
157
|
+
const instance = new InstanceImpl({
|
|
158
|
+
kv: new MemoryKvStore(),
|
|
159
|
+
repository: new MemoryRepository(),
|
|
160
|
+
pages: { css }
|
|
161
|
+
});
|
|
162
|
+
instance.createBot("alpha", { username: "alphabot" });
|
|
163
|
+
const response = await instance.fetch(new Request("https://example.com/"), void 0);
|
|
164
|
+
const html = await response.text();
|
|
165
|
+
assert.ok(html.includes(css));
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
//#endregion
|
|
170
|
+
//# sourceMappingURL=pages.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pages.test.js","names":["messageId: Uuid","repository: MemoryRepository","identifier: string"],"sources":["../src/pages.test.ts"],"sourcesContent":["// BotKit by Fedify: A framework for creating ActivityPub bots\n// Copyright (C) 2025–2026 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 { MemoryKvStore } from \"@fedify/fedify/federation\";\nimport { Create, Note, PUBLIC_COLLECTION } from \"@fedify/vocab\";\nimport assert from \"node:assert\";\nimport { describe, test } from \"node:test\";\nimport { BotImpl } from \"./bot-impl.ts\";\nimport { InstanceImpl } from \"./instance-impl.ts\";\nimport { MemoryRepository, type Uuid } from \"./repository.ts\";\n\nconst messageId: Uuid = \"01941f29-7c00-7fe8-ab0a-7b593990a3c0\";\n\nasync function seedMessage(\n repository: MemoryRepository,\n identifier: string,\n): Promise<void> {\n await repository.addMessage(\n identifier,\n messageId,\n new Create({\n id: new URL(\n `https://example.com/ap/actor/${identifier}/create/${messageId}`,\n ),\n actor: new URL(`https://example.com/ap/actor/${identifier}`),\n to: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\n `https://example.com/ap/actor/${identifier}/note/${messageId}`,\n ),\n attribution: new URL(`https://example.com/ap/actor/${identifier}`),\n to: 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 );\n}\n\ndescribe(\"single-bot web pages\", () => {\n test(\"serve the bot at the web root\", async () => {\n const repository = new MemoryRepository();\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n username: \"mybot\",\n name: \"My Bot\",\n });\n await seedMessage(repository, \"bot\");\n const profile = await bot.fetch(\n new Request(\"https://example.com/\"),\n undefined,\n );\n assert.deepStrictEqual(profile.status, 200);\n const html = await profile.text();\n assert.ok(html.includes(\"@mybot@example.com\"));\n assert.ok(html.includes('action=\"/follow\"'));\n\n const message = await bot.fetch(\n new Request(`https://example.com/message/${messageId}`),\n undefined,\n );\n assert.deepStrictEqual(message.status, 200);\n\n const feed = await bot.fetch(\n new Request(\"https://example.com/feed.xml\"),\n undefined,\n );\n assert.deepStrictEqual(feed.status, 200);\n assert.ok(\n feed.headers.get(\"Content-Type\")?.startsWith(\"application/atom+xml\"),\n );\n });\n\n test(\"use root-relative web URLs\", () => {\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"mybot\",\n });\n assert.deepStrictEqual(\n bot.instance.getBotWebUrl(bot, \"https://example.com\").href,\n \"https://example.com/\",\n );\n assert.deepStrictEqual(\n bot.instance.getMessageWebUrl(bot, messageId, \"https://example.com\")\n .href,\n `https://example.com/message/${messageId}`,\n );\n });\n});\n\ndescribe(\"multi-bot web pages\", () => {\n function createInstanceWithBots(): {\n instance: InstanceImpl<void>;\n repository: MemoryRepository;\n } {\n const repository = new MemoryRepository();\n const instance = new InstanceImpl<void>({\n kv: new MemoryKvStore(),\n repository,\n });\n instance.createBot(\"alpha\", { username: \"alphabot\", name: \"Alpha\" });\n instance.createBot(\"beta\", { username: \"betabot\", name: \"Beta\" });\n return { instance, repository };\n }\n\n test(\"list the hosted bots at the web root\", async () => {\n const { instance } = createInstanceWithBots();\n const response = await instance.fetch(\n new Request(\"https://example.com/\"),\n undefined,\n );\n assert.deepStrictEqual(response.status, 200);\n const html = await response.text();\n assert.ok(html.includes(\"@alphabot@example.com\"));\n assert.ok(html.includes(\"@betabot@example.com\"));\n assert.ok(html.includes('href=\"/@alphabot\"'));\n });\n\n test(\"serve per-bot profiles under /@{username}\", async () => {\n const { instance } = createInstanceWithBots();\n const response = await instance.fetch(\n new Request(\"https://example.com/@alphabot\"),\n undefined,\n );\n assert.deepStrictEqual(response.status, 200);\n const html = await response.text();\n assert.ok(html.includes(\"@alphabot@example.com\"));\n assert.ok(html.includes('action=\"/@alphabot/follow\"'));\n assert.ok(!html.includes(\"@betabot@example.com\"));\n\n const unknown = await instance.fetch(\n new Request(\"https://example.com/@nobody\"),\n undefined,\n );\n assert.deepStrictEqual(unknown.status, 404);\n });\n\n test(\"serve per-bot message permalinks and feeds\", async () => {\n const { instance, repository } = createInstanceWithBots();\n await seedMessage(repository, \"alpha\");\n\n const message = await instance.fetch(\n new Request(`https://example.com/@alphabot/${messageId}`),\n undefined,\n );\n assert.deepStrictEqual(message.status, 200);\n\n // Another bot's path must not serve the message:\n const cross = await instance.fetch(\n new Request(`https://example.com/@betabot/${messageId}`),\n undefined,\n );\n assert.deepStrictEqual(cross.status, 404);\n\n const feed = await instance.fetch(\n new Request(\"https://example.com/@alphabot/feed.xml\"),\n undefined,\n );\n assert.deepStrictEqual(feed.status, 200);\n assert.ok(\n feed.headers.get(\"Content-Type\")?.startsWith(\"application/atom+xml\"),\n );\n const followers = await instance.fetch(\n new Request(\"https://example.com/@alphabot/followers\"),\n undefined,\n );\n assert.deepStrictEqual(followers.status, 200);\n });\n\n test(\"use username-based web URLs\", () => {\n const { instance } = createInstanceWithBots();\n const alpha = instance.getBot(\"alpha\")!;\n assert.deepStrictEqual(\n instance.getBotWebUrl(alpha, \"https://example.com\").href,\n \"https://example.com/@alphabot\",\n );\n assert.deepStrictEqual(\n instance.getMessageWebUrl(alpha, messageId, \"https://example.com\").href,\n `https://example.com/@alphabot/${messageId}`,\n );\n });\n\n test(\"advertise the web URL on the actor\", async () => {\n const { instance } = createInstanceWithBots();\n const response = await instance.fetch(\n new Request(\"https://example.com/ap/actor/alpha\", {\n headers: { Accept: \"application/activity+json\" },\n }),\n undefined,\n );\n assert.deepStrictEqual(response.status, 200);\n const actor = await response.json();\n assert.deepStrictEqual(actor.url, \"https://example.com/@alphabot\");\n });\n});\n\ndescribe(\"usernames requiring percent-encoding\", () => {\n test(\"keep web paths and routes consistent\", async () => {\n const instance = new InstanceImpl<void>({\n kv: new MemoryKvStore(),\n repository: new MemoryRepository(),\n });\n instance.createBot(\"alpha\", { username: \"weird+bot\" });\n instance.createBot(\"beta\", { username: \"betabot\" });\n const alpha = instance.getBot(\"alpha\")!;\n const url = instance.getBotWebUrl(alpha, \"https://example.com\");\n assert.deepStrictEqual(url.href, \"https://example.com/@weird%2Bbot\");\n const response = await instance.fetch(new Request(url), undefined);\n assert.deepStrictEqual(response.status, 200);\n const html = await response.text();\n assert.ok(html.includes(\"weird+bot\"));\n });\n});\n\ndescribe(\"custom CSS\", () => {\n const css = \"main > p { color: red; }\";\n\n test(\"is not HTML-escaped on single-bot pages\", async () => {\n const bot = new BotImpl<void>({\n kv: new MemoryKvStore(),\n username: \"mybot\",\n pages: { css },\n });\n const response = await bot.fetch(\n new Request(\"https://example.com/\"),\n undefined,\n );\n const html = await response.text();\n assert.ok(html.includes(css));\n });\n\n test(\"is not HTML-escaped on the instance index\", async () => {\n const instance = new InstanceImpl<void>({\n kv: new MemoryKvStore(),\n repository: new MemoryRepository(),\n pages: { css },\n });\n instance.createBot(\"alpha\", { username: \"alphabot\" });\n const response = await instance.fetch(\n new Request(\"https://example.com/\"),\n undefined,\n );\n const html = await response.text();\n assert.ok(html.includes(css));\n });\n});\n"],"mappings":"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"}
|