From 12a81f534930c7f3e9b34b56a48e52b2ef5a850f Mon Sep 17 00:00:00 2001
From: "Kim, Hyeonseo"
Date: Mon, 1 Sep 2025 13:45:02 +0900
Subject: [PATCH 01/14] feat: add follow button
---
.../botkit/src/components/FollowButton.tsx | 63 +++++++++++++++++++
packages/botkit/src/pages.tsx | 6 +-
2 files changed, 67 insertions(+), 2 deletions(-)
create mode 100644 packages/botkit/src/components/FollowButton.tsx
diff --git a/packages/botkit/src/components/FollowButton.tsx b/packages/botkit/src/components/FollowButton.tsx
new file mode 100644
index 0000000..a49ccc7
--- /dev/null
+++ b/packages/botkit/src/components/FollowButton.tsx
@@ -0,0 +1,63 @@
+/** @jsxImportSource hono/jsx */
+import type { BotImpl } from "../bot-impl.ts";
+
+export interface FollowButtonProps {
+ readonly bot: BotImpl;
+}
+
+export function FollowButton({ bot }: FollowButtonProps) {
+ return (
+ <>
+
+
+
+ >
+ );
+}
diff --git a/packages/botkit/src/pages.tsx b/packages/botkit/src/pages.tsx
index 8ae054e..156168f 100644
--- a/packages/botkit/src/pages.tsx
+++ b/packages/botkit/src/pages.tsx
@@ -32,6 +32,7 @@ import type { BotImpl } from "./bot-impl.ts";
import { Layout } from "./components/Layout.tsx";
import { Message } from "./components/Message.tsx";
import { Follower } from "./components/Follower.tsx";
+import { FollowButton } from "./components/FollowButton.tsx";
import { getMessageClass, isMessageObject, textXss } from "./message-impl.ts";
import type { MessageClass } from "./message.ts";
import type { Uuid } from "./repository.ts";
@@ -154,8 +155,9 @@ app.get("/", async (c) => {
{postsCount === 1
? `1 post`
: `${postsCount.toLocaleString("en")} posts`}
-
- {" "}
+ {" "}
+ ·{" "}
+
{summary &&
From 1f798b9f2cf22bf1c82475b8aecfebf85453c808 Mon Sep 17 00:00:00 2001
From: "Kim, Hyeonseo"
Date: Mon, 1 Sep 2025 14:48:14 +0900
Subject: [PATCH 02/14] feat: add /follow post route to redirect follow page
---
packages/botkit/src/pages.tsx | 70 +++++++++++++++++++++++++++++++++--
1 file changed, 66 insertions(+), 4 deletions(-)
diff --git a/packages/botkit/src/pages.tsx b/packages/botkit/src/pages.tsx
index 156168f..109eb63 100644
--- a/packages/botkit/src/pages.tsx
+++ b/packages/botkit/src/pages.tsx
@@ -29,10 +29,10 @@ import {
import { Hono } from "hono";
import { decode } from "html-entities";
import type { BotImpl } from "./bot-impl.ts";
+import { FollowButton } from "./components/FollowButton.tsx";
+import { Follower } from "./components/Follower.tsx";
import { Layout } from "./components/Layout.tsx";
import { Message } from "./components/Message.tsx";
-import { Follower } from "./components/Follower.tsx";
-import { FollowButton } from "./components/FollowButton.tsx";
import { getMessageClass, isMessageObject, textXss } from "./message-impl.ts";
import type { MessageClass } from "./message.ts";
import type { Uuid } from "./repository.ts";
@@ -156,8 +156,7 @@ app.get("/", async (c) => {
? `1 post`
: `${postsCount.toLocaleString("en")} posts`}
{" "}
- ·{" "}
-
+ ·
{summary &&
@@ -433,6 +432,69 @@ app.get("/feed.xml", async (c) => {
return response;
});
+app.post("/follow", async (c) => {
+ const { bot } = c.env;
+ const ctx = bot.federation.createContext(c.req.raw, c.env.contextData);
+ const url = new URL(c.req.url);
+ const botHandle = `@${bot.username}@${url.host}`;
+
+ const formData = await c.req.formData();
+ let followerHandle = formData.get("handle")?.toString();
+
+ try {
+ if (!followerHandle) {
+ throw new Error("No followerHandle!");
+ }
+
+ if (followerHandle.startsWith("@")) {
+ followerHandle = followerHandle.slice(1);
+ }
+
+ const webfingerData = await ctx
+ .lookupWebFinger(`acct:${followerHandle}`);
+
+ if (!webfingerData?.links) {
+ return c.json({ error: "No links found in webfinger data" }, 400);
+ }
+
+ console.log(webfingerData);
+
+ const subscribeLink = webfingerData.links.find(
+ (link) => link.rel === "http://ostatus.org/schema/1.0/subscribe",
+ ) as { template?: string } | undefined;
+
+ if (subscribeLink?.template) {
+ const botActorUri = ctx.getActorUri(bot.identifier);
+ const followUrl = subscribeLink.template.replace(
+ "{uri}",
+ encodeURIComponent(botActorUri.href),
+ );
+ return c.redirect(followUrl);
+ }
+
+ const profileLink = webfingerData.links.find(
+ (link) => link.rel === "http://webfinger.net/rel/profile-page",
+ ) as { href?: string } | undefined;
+
+ if (profileLink?.href) {
+ const followerUsername = followerHandle.split("@")[0];
+ const followUrl = profileLink.href.replace(
+ `@${followerUsername}`,
+ botHandle,
+ );
+ return c.redirect(followUrl);
+ }
+
+ return c.json({
+ error: "No follow link found in webfinger data",
+ data: webfingerData,
+ }, 400);
+ } catch (error) {
+ console.error("Follow request error:", error);
+ return c.json({ error: error }, 400);
+ }
+});
+
interface GetPostsOptions {
readonly hashtag?: string;
readonly offset?: Temporal.Instant;
From 63e89dbb8131409ff072deafe799dd33962cc1fd Mon Sep 17 00:00:00 2001
From: "Kim, Hyeonseo"
Date: Mon, 1 Sep 2025 15:10:02 +0900
Subject: [PATCH 03/14] fix: error message on /follow
---
packages/botkit/src/pages.tsx | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/packages/botkit/src/pages.tsx b/packages/botkit/src/pages.tsx
index 109eb63..02ab560 100644
--- a/packages/botkit/src/pages.tsx
+++ b/packages/botkit/src/pages.tsx
@@ -491,7 +491,10 @@ app.post("/follow", async (c) => {
}, 400);
} catch (error) {
console.error("Follow request error:", error);
- return c.json({ error: error }, 400);
+ if (error instanceof Error && error.message === "No followerHandle!") {
+ return c.json({ error: "Follower handle is required." }, 400);
+ }
+ return c.json({ error: "An internal server error occurred." }, 500);
}
});
From 45eb14ef335b20cab9d71e2a15af51780476a6fe Mon Sep 17 00:00:00 2001
From: "Kim, Hyeonseo"
Date: Mon, 1 Sep 2025 15:18:02 +0900
Subject: [PATCH 04/14] remove: debug code
---
packages/botkit/src/pages.tsx | 2 --
1 file changed, 2 deletions(-)
diff --git a/packages/botkit/src/pages.tsx b/packages/botkit/src/pages.tsx
index 02ab560..d478245 100644
--- a/packages/botkit/src/pages.tsx
+++ b/packages/botkit/src/pages.tsx
@@ -457,8 +457,6 @@ app.post("/follow", async (c) => {
return c.json({ error: "No links found in webfinger data" }, 400);
}
- console.log(webfingerData);
-
const subscribeLink = webfingerData.links.find(
(link) => link.rel === "http://ostatus.org/schema/1.0/subscribe",
) as { template?: string } | undefined;
From ee767f9471fe66c64a70ed924c481f8f3219a54c Mon Sep 17 00:00:00 2001
From: "Kim, Hyeonseo"
Date: Mon, 1 Sep 2025 19:01:41 +0900
Subject: [PATCH 05/14] remove: heuristic fallback
---
packages/botkit/src/pages.tsx | 15 ---------------
1 file changed, 15 deletions(-)
diff --git a/packages/botkit/src/pages.tsx b/packages/botkit/src/pages.tsx
index d478245..f0fe6bc 100644
--- a/packages/botkit/src/pages.tsx
+++ b/packages/botkit/src/pages.tsx
@@ -470,25 +470,10 @@ app.post("/follow", async (c) => {
return c.redirect(followUrl);
}
- const profileLink = webfingerData.links.find(
- (link) => link.rel === "http://webfinger.net/rel/profile-page",
- ) as { href?: string } | undefined;
-
- if (profileLink?.href) {
- const followerUsername = followerHandle.split("@")[0];
- const followUrl = profileLink.href.replace(
- `@${followerUsername}`,
- botHandle,
- );
- return c.redirect(followUrl);
- }
-
return c.json({
error: "No follow link found in webfinger data",
- data: webfingerData,
}, 400);
} catch (error) {
- console.error("Follow request error:", error);
if (error instanceof Error && error.message === "No followerHandle!") {
return c.json({ error: "Follower handle is required." }, 400);
}
From ac9b6bc5b97a128f1ac35c83dd2f5c6f680c1e1d Mon Sep 17 00:00:00 2001
From: "Kim, Hyeonseo"
Date: Mon, 1 Sep 2025 19:44:52 +0900
Subject: [PATCH 06/14] fix: typo in error message
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Hong Minhee (洪 民憙)
---
packages/botkit/src/pages.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/botkit/src/pages.tsx b/packages/botkit/src/pages.tsx
index f0fe6bc..04f19de 100644
--- a/packages/botkit/src/pages.tsx
+++ b/packages/botkit/src/pages.tsx
@@ -471,7 +471,7 @@ app.post("/follow", async (c) => {
}
return c.json({
- error: "No follow link found in webfinger data",
+ error: "No follow link found in WebFinger data.",
}, 400);
} catch (error) {
if (error instanceof Error && error.message === "No followerHandle!") {
From 82d8246778e60d15dd888f847794298252471c48 Mon Sep 17 00:00:00 2001
From: "Kim, Hyeonseo"
Date: Mon, 1 Sep 2025 19:46:20 +0900
Subject: [PATCH 07/14] refactor: change no handle error logic
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Hong Minhee (洪 民憙)
---
packages/botkit/src/pages.tsx | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/packages/botkit/src/pages.tsx b/packages/botkit/src/pages.tsx
index 04f19de..3acd541 100644
--- a/packages/botkit/src/pages.tsx
+++ b/packages/botkit/src/pages.tsx
@@ -443,7 +443,7 @@ app.post("/follow", async (c) => {
try {
if (!followerHandle) {
- throw new Error("No followerHandle!");
+ return c.json({ error: "Follower handle is required." }, 400);
}
if (followerHandle.startsWith("@")) {
@@ -473,10 +473,7 @@ app.post("/follow", async (c) => {
return c.json({
error: "No follow link found in WebFinger data.",
}, 400);
- } catch (error) {
- if (error instanceof Error && error.message === "No followerHandle!") {
- return c.json({ error: "Follower handle is required." }, 400);
- }
+ } catch (_error) {
return c.json({ error: "An internal server error occurred." }, 500);
}
});
From 71ef6fb2862d5ca05b43bf73f4c86a30a4241a8b Mon Sep 17 00:00:00 2001
From: "Kim, Hyeonseo"
Date: Mon, 1 Sep 2025 20:17:35 +0900
Subject: [PATCH 08/14] dep: add url-template
---
deno.lock | 2 ++
packages/botkit/deno.json | 1 +
packages/botkit/package.json | 1 +
pnpm-lock.yaml | 3 +++
4 files changed, 7 insertions(+)
diff --git a/deno.lock b/deno.lock
index 5640581..20f2ca0 100644
--- a/deno.lock
+++ b/deno.lock
@@ -757,6 +757,7 @@
"npm:markdown-it@^14.1.0",
"npm:mime-db@^1.54.0",
"npm:tsdown@~0.12.8",
+ "npm:url-template@^3.1.1",
"npm:uuid@^11.1.0",
"npm:xss@^1.0.15"
],
@@ -768,6 +769,7 @@
"npm:html-entities@^2.6.0",
"npm:markdown-it@^14.1.0",
"npm:mime-db@^1.54.0",
+ "npm:url-template@^3.1.1",
"npm:uuid@^11.1.0",
"npm:xss@^1.0.15"
]
diff --git a/packages/botkit/deno.json b/packages/botkit/deno.json
index cee52dc..9b986ae 100644
--- a/packages/botkit/deno.json
+++ b/packages/botkit/deno.json
@@ -23,6 +23,7 @@
"markdown-it": "npm:markdown-it@^14.1.0",
"mime-db": "npm:mime-db@^1.54.0",
"tsdown": "npm:tsdown@^0.12.8",
+ "url-template": "npm:url-template@^3.1.1",
"uuid": "npm:uuid@^11.1.0",
"xss": "npm:xss@^1.0.15"
},
diff --git a/packages/botkit/package.json b/packages/botkit/package.json
index 9633f09..27d4cf2 100644
--- a/packages/botkit/package.json
+++ b/packages/botkit/package.json
@@ -94,6 +94,7 @@
"html-entities": "^2.6.0",
"markdown-it": "^14.1.0",
"mime-db": "^1.54.0",
+ "url-template": "^3.1.1",
"uuid": "^11.1.0",
"x-forwarded-fetch": "catalog:",
"xss": "^1.0.15"
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index eca3573..d1fdce5 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -122,6 +122,9 @@ importers:
mime-db:
specifier: ^1.54.0
version: 1.54.0
+ url-template:
+ specifier: ^3.1.1
+ version: 3.1.1
uuid:
specifier: ^11.1.0
version: 11.1.0
From 313a07eda843bec22bf7361b92135b2bbb45efd9 Mon Sep 17 00:00:00 2001
From: "Kim, Hyeonseo"
Date: Mon, 1 Sep 2025 20:18:29 +0900
Subject: [PATCH 09/14] feat: use url template in followUrl
---
packages/botkit/src/pages.tsx | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/packages/botkit/src/pages.tsx b/packages/botkit/src/pages.tsx
index 3acd541..577965b 100644
--- a/packages/botkit/src/pages.tsx
+++ b/packages/botkit/src/pages.tsx
@@ -28,6 +28,7 @@ import {
} from "@fedify/fedify/vocab";
import { Hono } from "hono";
import { decode } from "html-entities";
+import { parseTemplate } from "url-template";
import type { BotImpl } from "./bot-impl.ts";
import { FollowButton } from "./components/FollowButton.tsx";
import { Follower } from "./components/Follower.tsx";
@@ -463,10 +464,10 @@ app.post("/follow", async (c) => {
if (subscribeLink?.template) {
const botActorUri = ctx.getActorUri(bot.identifier);
- const followUrl = subscribeLink.template.replace(
- "{uri}",
- encodeURIComponent(botActorUri.href),
- );
+ const followUrlTemplate = parseTemplate(subscribeLink.template);
+ const followUrl = followUrlTemplate.expand({
+ uri: botActorUri.href,
+ });
return c.redirect(followUrl);
}
From e8a47f703dc59834a89be72e5b670fbd8970cd4b Mon Sep 17 00:00:00 2001
From: "Kim, Hyeonseo"
Date: Mon, 1 Sep 2025 20:19:26 +0900
Subject: [PATCH 10/14] remove: unused bot handle constant
---
packages/botkit/src/pages.tsx | 2 --
1 file changed, 2 deletions(-)
diff --git a/packages/botkit/src/pages.tsx b/packages/botkit/src/pages.tsx
index 577965b..6e18da0 100644
--- a/packages/botkit/src/pages.tsx
+++ b/packages/botkit/src/pages.tsx
@@ -436,8 +436,6 @@ app.get("/feed.xml", async (c) => {
app.post("/follow", async (c) => {
const { bot } = c.env;
const ctx = bot.federation.createContext(c.req.raw, c.env.contextData);
- const url = new URL(c.req.url);
- const botHandle = `@${bot.username}@${url.host}`;
const formData = await c.req.formData();
let followerHandle = formData.get("handle")?.toString();
From ced9a137a18059dd9922748bfc6fef998b47136e Mon Sep 17 00:00:00 2001
From: "Kim, Hyeonseo"
Date: Mon, 1 Sep 2025 20:32:50 +0900
Subject: [PATCH 11/14] docs: add changelog
---
CHANGES.md | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/CHANGES.md b/CHANGES.md
index 9e02463..25593c3 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -6,6 +6,15 @@ Version 0.4.0
To be released.
+### @fedify/botkit
+
+ - Added remote follow button. [[#10], [#14] by Hyeonseo Kim]
+
+ - Added Follow button and modal on main page.
+ - Added `POST /follow` route to handle remote follow action.
+
+[#10]: https://github.com/fedify-dev/botkit/issues/10
+[#14]: https://github.com/fedify-dev/botkit/pull/14
Version 0.3.0
-------------
From e5be1092880eeaa1911a1aebb9d591e498651f53 Mon Sep 17 00:00:00 2001
From: "Kim, Hyeonseo"
Date: Wed, 3 Sep 2025 16:51:40 +0900
Subject: [PATCH 12/14] feat: change json to html error page
---
packages/botkit/src/pages.tsx | 63 +++++++++++++++++++++++++++++++----
1 file changed, 57 insertions(+), 6 deletions(-)
diff --git a/packages/botkit/src/pages.tsx b/packages/botkit/src/pages.tsx
index 6e18da0..a491ffd 100644
--- a/packages/botkit/src/pages.tsx
+++ b/packages/botkit/src/pages.tsx
@@ -436,13 +436,25 @@ app.get("/feed.xml", async (c) => {
app.post("/follow", async (c) => {
const { bot } = c.env;
const ctx = bot.federation.createContext(c.req.raw, c.env.contextData);
+ const url = new URL(c.req.url);
const formData = await c.req.formData();
let followerHandle = formData.get("handle")?.toString();
try {
if (!followerHandle) {
- return c.json({ error: "Follower handle is required." }, 400);
+ return c.html(
+
+
+ Error
+ Follower handle is required.
+
+ Go back
+
+
+ ,
+ 400,
+ );
}
if (followerHandle.startsWith("@")) {
@@ -453,7 +465,21 @@ app.post("/follow", async (c) => {
.lookupWebFinger(`acct:${followerHandle}`);
if (!webfingerData?.links) {
- return c.json({ error: "No links found in webfinger data" }, 400);
+ return c.html(
+
+
+ Error
+
+ No links found in webfinger data for{" "}
+ @{followerHandle}
.
+
+
+ Go back
+
+
+ ,
+ 400,
+ );
}
const subscribeLink = webfingerData.links.find(
@@ -469,11 +495,36 @@ app.post("/follow", async (c) => {
return c.redirect(followUrl);
}
- return c.json({
- error: "No follow link found in WebFinger data.",
- }, 400);
+ return c.html(
+
+
+ Error
+
+ No follow link found in WebFinger data for{" "}
+ @{followerHandle}
.
+
+
+ Go back
+
+
+ ,
+ 400,
+ );
} catch (_error) {
- return c.json({ error: "An internal server error occurred." }, 500);
+ return c.html(
+
+
+ Internal Server Error
+
+ An internal server error occurred while processing your request.
+
+
+ Go back
+
+
+ ,
+ 500,
+ );
}
});
From fd5ffcaf89f13c76c2dd9c22aab7911e87834a1c Mon Sep 17 00:00:00 2001
From: "Kim, Hyeonseo"
Date: Wed, 3 Sep 2025 16:52:28 +0900
Subject: [PATCH 13/14] type: remove type assertion
---
packages/botkit/src/pages.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/botkit/src/pages.tsx b/packages/botkit/src/pages.tsx
index a491ffd..3a2cb24 100644
--- a/packages/botkit/src/pages.tsx
+++ b/packages/botkit/src/pages.tsx
@@ -484,7 +484,7 @@ app.post("/follow", async (c) => {
const subscribeLink = webfingerData.links.find(
(link) => link.rel === "http://ostatus.org/schema/1.0/subscribe",
- ) as { template?: string } | undefined;
+ );
if (subscribeLink?.template) {
const botActorUri = ctx.getActorUri(bot.identifier);
From defa2d7cc71abc9a38a498e743d04dc374681ee5 Mon Sep 17 00:00:00 2001
From: "Kim, Hyeonseo"
Date: Wed, 3 Sep 2025 17:09:32 +0900
Subject: [PATCH 14/14] dep: set @fedify/fedify version 1.9.0-dev.1516+8f42bff1
---
deno.json | 2 +-
deno.lock | 95 +++++++++++++++++++++++----------------------
pnpm-lock.yaml | 34 ++++++++--------
pnpm-workspace.yaml | 2 +-
4 files changed, 68 insertions(+), 65 deletions(-)
diff --git a/deno.json b/deno.json
index 34491cb..a754c93 100644
--- a/deno.json
+++ b/deno.json
@@ -8,7 +8,7 @@
"temporal"
],
"imports": {
- "@fedify/fedify": "jsr:@fedify/fedify@^1.8.8",
+ "@fedify/fedify": "jsr:@fedify/fedify@1.9.0-dev.1516+8f42bff1",
"@logtape/logtape": "jsr:@logtape/logtape@^1.0.4",
"@std/fs": "jsr:@std/fs@^1.0.19",
"@std/path": "jsr:@std/path@^1.1.1",
diff --git a/deno.lock b/deno.lock
index 20f2ca0..a92aa59 100644
--- a/deno.lock
+++ b/deno.lock
@@ -2,11 +2,11 @@
"version": "5",
"specifiers": {
"jsr:@es-toolkit/es-toolkit@^1.39.5": "1.39.10",
- "jsr:@fedify/fedify@^1.8.8": "1.8.8",
+ "jsr:@fedify/fedify@1.9.0-dev.1516+8f42bff1": "1.9.0-dev.1516+8f42bff1",
"jsr:@fedify/markdown-it-hashtag@0.3": "0.3.0",
"jsr:@fedify/markdown-it-mention@0.3": "0.3.0",
"jsr:@hongminhee/x-forwarded-fetch@0.2": "0.2.0",
- "jsr:@hono/hono@^4.8.2": "4.9.4",
+ "jsr:@hono/hono@^4.8.2": "4.9.6",
"jsr:@hugoalh/http-header-link@^1.0.2": "1.0.3",
"jsr:@hugoalh/is-string-singleline@^1.0.4": "1.0.5",
"jsr:@logtape/logtape@1": "1.0.4",
@@ -34,7 +34,7 @@
"npm:multicodec@^3.2.1": "3.2.1",
"npm:pkijs@^3.2.4": "3.2.5",
"npm:structured-field-values@^2.0.4": "2.0.4",
- "npm:tsdown@~0.12.8": "0.12.9_rolldown@1.0.0-beta.34",
+ "npm:tsdown@~0.12.8": "0.12.9_rolldown@1.0.0-beta.33",
"npm:uri-template-router@^0.0.17": "0.0.17",
"npm:url-template@^3.1.1": "3.1.1",
"npm:uuid@^11.1.0": "11.1.0",
@@ -44,8 +44,8 @@
"@es-toolkit/es-toolkit@1.39.10": {
"integrity": "8757072a13aa64b3b349ba2b9d7d22fbe7ea6f138506c6cd2222d767cd79918f"
},
- "@fedify/fedify@1.8.8": {
- "integrity": "6f8d83e26771415e2b062a264a6d09bc4800eff2519ea23cbb26e6e38c6a0396",
+ "@fedify/fedify@1.9.0-dev.1516+8f42bff1": {
+ "integrity": "346a26175f9b552e77b44ba56936acff5483b3387d0dc29bec23fe85db2ba5cc",
"dependencies": [
"jsr:@es-toolkit/es-toolkit",
"jsr:@hugoalh/http-header-link",
@@ -91,6 +91,9 @@
"@hono/hono@4.9.4": {
"integrity": "de006e32f3bab18e5a5bed4c75c5e0aaa46958d3653e6646b534a874d690dccc"
},
+ "@hono/hono@4.9.6": {
+ "integrity": "b85abb0013d167a290b1808d1d4d542dee269df31d4f47122023259fdd7e184b"
+ },
"@hugoalh/http-header-link@1.0.3": {
"integrity": "3372096a73d755e3351f7fbd7155db7725874c2682a594a655580e3866563024",
"dependencies": [
@@ -236,11 +239,11 @@
"@opentelemetry/semantic-conventions@1.36.0": {
"integrity": "sha512-TtxJSRD8Ohxp6bKkhrm27JRHAxPczQA7idtcTOMYI+wQRRrfgqxHv1cFbCApcSnNjtXkmzFozn6jQtFrOmbjPQ=="
},
- "@oxc-project/runtime@0.82.3": {
- "integrity": "sha512-LNh5GlJvYHAnMurO+EyA8jJwN1rki7l3PSHuosDh2I7h00T6/u9rCkUjg/SvPmT1CZzvhuW0y+gf7jcqUy/Usg=="
+ "@oxc-project/runtime@0.82.2": {
+ "integrity": "sha512-cYxcj5CPn/vo5QSpCZcYzBiLidU5+GlFSqIeNaMgBDtcVRBsBJHZg3pHw999W6nHamFQ1EHuPPByB26tjaJiJw=="
},
- "@oxc-project/types@0.82.3": {
- "integrity": "sha512-6nCUxBnGX0c6qfZW5MaF6/fmu5dHJDMiMPaioKHKs5mi5+8/FHQ7WGjgQIz1zxpmceMYfdIXkOaLYE+ejbuOtA=="
+ "@oxc-project/types@0.82.2": {
+ "integrity": "sha512-WMGSwd9FsNBs/WfqIOH0h3k1LBdjZJQGYjGnC+vla/fh6HUsu5HzGPerRljiq1hgMQ6gs031YJR12VyP57b/hQ=="
},
"@phensley/language-tag@1.13.1": {
"integrity": "sha512-0cqJT7yC1wz0LlT63gs6lfTSgvedWA+Msg2tDbp9b5NCF9CTyLZ/9UbncBlXRHHvugbhtlT3NjM6lvwK3mrIoA==",
@@ -254,80 +257,80 @@
"quansync"
]
},
- "@rolldown/binding-android-arm64@1.0.0-beta.34": {
- "integrity": "sha512-jf5GNe5jP3Sr1Tih0WKvg2bzvh5T/1TA0fn1u32xSH7ca/p5t+/QRr4VRFCV/na5vjwKEhwWrChsL2AWlY+eoA==",
+ "@rolldown/binding-android-arm64@1.0.0-beta.33": {
+ "integrity": "sha512-xhDQXKftRkEULIxCddrKMR8y0YO/Y+6BKk/XrQP2B29YjV2wr8DByoEz+AHX9BfLHb2srfpdN46UquBW2QXWpQ==",
"os": ["android"],
"cpu": ["arm64"]
},
- "@rolldown/binding-darwin-arm64@1.0.0-beta.34": {
- "integrity": "sha512-2F/TqH4QuJQ34tgWxqBjFL3XV1gMzeQgUO8YRtCPGBSP0GhxtoFzsp7KqmQEothsxztlv+KhhT9Dbg3HHwHViQ==",
+ "@rolldown/binding-darwin-arm64@1.0.0-beta.33": {
+ "integrity": "sha512-7lhhY08v5ZtRq8JJQaJ49fnJombAPnqllKKCDLU/UvaqNAOEyTGC8J1WVOLC4EA4zbXO5U3CCRgVGyAFNH2VtQ==",
"os": ["darwin"],
"cpu": ["arm64"]
},
- "@rolldown/binding-darwin-x64@1.0.0-beta.34": {
- "integrity": "sha512-E1QuFslgLWbHQ8Qli/AqUKdfg0pockQPwRxVbhNQ74SciZEZpzLaujkdmOLSccMlSXDfFCF8RPnMoRAzQ9JV8Q==",
+ "@rolldown/binding-darwin-x64@1.0.0-beta.33": {
+ "integrity": "sha512-U2iGjcDV7NWyYyhap8YuY0nwrLX6TvX/9i7gBtdEMPm9z3wIUVGNMVdGlA43uqg7xDpRGpEqGnxbeDgiEwYdnA==",
"os": ["darwin"],
"cpu": ["x64"]
},
- "@rolldown/binding-freebsd-x64@1.0.0-beta.34": {
- "integrity": "sha512-VS8VInNCwnkpI9WeQaWu3kVBq9ty6g7KrHdLxYMzeqz24+w9hg712TcWdqzdY6sn+24lUoMD9jTZrZ/qfVpk0g==",
+ "@rolldown/binding-freebsd-x64@1.0.0-beta.33": {
+ "integrity": "sha512-gd6ASromVHFLlzrjJWMG5CXHkS7/36DEZ8HhvGt2NN8eZALCIuyEx8HMMLqvKA7z4EAztVkdToVrdxpGMsKZxw==",
"os": ["freebsd"],
"cpu": ["x64"]
},
- "@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.34": {
- "integrity": "sha512-4St4emjcnULnxJYb/5ZDrH/kK/j6PcUgc3eAqH5STmTrcF+I9m/X2xvSF2a2bWv1DOQhxBewThu0KkwGHdgu5w==",
+ "@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.33": {
+ "integrity": "sha512-xmeLfkfGthuynO1EpCdyTVr0r4G+wqvnKCuyR6rXOet+hLrq5HNAC2XtP/jU2TB4Bc6aiLYxl868B8CGtFDhcw==",
"os": ["linux"],
"cpu": ["arm"]
},
- "@rolldown/binding-linux-arm64-gnu@1.0.0-beta.34": {
- "integrity": "sha512-a737FTqhFUoWfnebS2SnQ2BS50p0JdukdkUBwy2J06j4hZ6Eej0zEB8vTfAqoCjn8BQKkXBy+3Sx0IRkgwz1gA==",
+ "@rolldown/binding-linux-arm64-gnu@1.0.0-beta.33": {
+ "integrity": "sha512-cHGp8yfHL4pes6uaLbO5L58ceFkUK4efd8iE86jClD1QPPDLKiqEXJCFYeuK3OfODuF5EBOmf0SlcUZNEYGdmw==",
"os": ["linux"],
"cpu": ["arm64"]
},
- "@rolldown/binding-linux-arm64-musl@1.0.0-beta.34": {
- "integrity": "sha512-NH+FeQWKyuw0k+PbXqpFWNfvD8RPvfJk766B/njdaWz4TmiEcSB0Nb6guNw1rBpM1FmltQYb3fFnTumtC6pRfA==",
+ "@rolldown/binding-linux-arm64-musl@1.0.0-beta.33": {
+ "integrity": "sha512-wZ1t7JAvVeFgskH1L9y7c47ITitPytpL0s8FmAT8pVfXcaTmS58ZyoXT+y6cz8uCkQnETjrX3YezTGI18u3ecg==",
"os": ["linux"],
"cpu": ["arm64"]
},
- "@rolldown/binding-linux-x64-gnu@1.0.0-beta.34": {
- "integrity": "sha512-Q3RSCivp8pNadYK8ke3hLnQk08BkpZX9BmMjgwae2FWzdxhxxUiUzd9By7kneUL0vRQ4uRnhD9VkFQ+Haeqdvw==",
+ "@rolldown/binding-linux-x64-gnu@1.0.0-beta.33": {
+ "integrity": "sha512-cDndWo3VEYbm7yeujOV6Ie2XHz0K8YX/R/vbNmMo03m1QwtBKKvbYNSyJb3B9+8igltDjd8zNM9mpiNNrq/ekQ==",
"os": ["linux"],
"cpu": ["x64"]
},
- "@rolldown/binding-linux-x64-musl@1.0.0-beta.34": {
- "integrity": "sha512-wDd/HrNcVoBhWWBUW3evJHoo7GJE/RofssBy3Dsiip05YUBmokQVrYAyrboOY4dzs/lJ7HYeBtWQ9hj8wlyF0A==",
+ "@rolldown/binding-linux-x64-musl@1.0.0-beta.33": {
+ "integrity": "sha512-bl7uzi6es/l6LT++NZcBpiX43ldLyKXCPwEZGY1rZJ99HQ7m1g3KxWwYCcGxtKjlb2ExVvDZicF6k+96vxOJKg==",
"os": ["linux"],
"cpu": ["x64"]
},
- "@rolldown/binding-openharmony-arm64@1.0.0-beta.34": {
- "integrity": "sha512-dH3FTEV6KTNWpYSgjSXZzeX7vLty9oBYn6R3laEdhwZftQwq030LKL+5wyQdlbX5pnbh4h127hpv3Hl1+sj8dg==",
+ "@rolldown/binding-openharmony-arm64@1.0.0-beta.33": {
+ "integrity": "sha512-TrgzQanpLgcmmzolCbYA9BPZgF1gYxkIGZhU/HROnJPsq67gcyaYw/JBLioqQLjIwMipETkn25YY799D2OZzJA==",
"os": ["openharmony"],
"cpu": ["arm64"]
},
- "@rolldown/binding-wasm32-wasi@1.0.0-beta.34": {
- "integrity": "sha512-y5BUf+QtO0JsIDKA51FcGwvhJmv89BYjUl8AmN7jqD6k/eU55mH6RJYnxwCsODq5m7KSSTigVb6O7/GqB8wbPw==",
+ "@rolldown/binding-wasm32-wasi@1.0.0-beta.33": {
+ "integrity": "sha512-z0LltdUfvoKak9SuaLz/M9AVSg+RTOZjFksbZXzC6Svl1odyW4ai21VHhZy3m2Faeeb/rl/9efVLayj+qYEGxw==",
"dependencies": [
"@napi-rs/wasm-runtime"
],
"cpu": ["wasm32"]
},
- "@rolldown/binding-win32-arm64-msvc@1.0.0-beta.34": {
- "integrity": "sha512-ga5hFhdTwpaNxEiuxZHWnD3ed0GBAzbgzS5tRHpe0ObptxM1a9Xrq6TVfNQirBLwb5Y7T/FJmJi3pmdLy95ljg==",
+ "@rolldown/binding-win32-arm64-msvc@1.0.0-beta.33": {
+ "integrity": "sha512-CpvOHyqDNOYx9riD4giyXQDIu72bWRU2Dwt1xFSPlBudk6NumK0OJl6Ch+LPnkp5podQHcQg0mMauAXPVKct7g==",
"os": ["win32"],
"cpu": ["arm64"]
},
- "@rolldown/binding-win32-ia32-msvc@1.0.0-beta.34": {
- "integrity": "sha512-4/MBp9T9eRnZskxWr8EXD/xHvLhdjWaeX/qY9LPRG1JdCGV3DphkLTy5AWwIQ5jhAy2ZNJR5z2fYRlpWU0sIyQ==",
+ "@rolldown/binding-win32-ia32-msvc@1.0.0-beta.33": {
+ "integrity": "sha512-/tNTvZTWHz6HiVuwpR3zR0kGIyCNb+/tFhnJmti+Aw2fAXs3l7Aj0DcXd0646eFKMX8L2w5hOW9H08FXTUkN0g==",
"os": ["win32"],
"cpu": ["ia32"]
},
- "@rolldown/binding-win32-x64-msvc@1.0.0-beta.34": {
- "integrity": "sha512-7O5iUBX6HSBKlQU4WykpUoEmb0wQmonb6ziKFr3dJTHud2kzDnWMqk344T0qm3uGv9Ddq6Re/94pInxo1G2d4w==",
+ "@rolldown/binding-win32-x64-msvc@1.0.0-beta.33": {
+ "integrity": "sha512-Bb2qK3z7g2mf4zaKRvkohHzweaP1lLbaoBmXZFkY6jJWMm0Z8Pfnh8cOoRlH1IVM1Ufbo8ZZ1WXp1LbOpRMtXw==",
"os": ["win32"],
"cpu": ["x64"]
},
- "@rolldown/pluginutils@1.0.0-beta.34": {
- "integrity": "sha512-LyAREkZHP5pMom7c24meKmJCdhf2hEyvam2q0unr3or9ydwDL+DJ8chTF6Av/RFPb3rH8UFBdMzO5MxTZW97oA=="
+ "@rolldown/pluginutils@1.0.0-beta.33": {
+ "integrity": "sha512-she25NCG6NoEPC/SEB4pHs5STcnfI4VBFOzjeI63maSPrWME5J2XC8ogrBgp8NaE/xzj28/kbpSaebiMvFRj+w=="
},
"@tybys/wasm-util@0.10.0": {
"integrity": "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==",
@@ -423,8 +426,8 @@
"diff@8.0.2": {
"integrity": "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg=="
},
- "dts-resolver@2.1.2": {
- "integrity": "sha512-xeXHBQkn2ISSXxbJWD828PFjtyg+/UrMDo7W4Ffcs7+YWCquxU8YjV1KoxuiL+eJ5pg3ll+bC6flVv61L3LKZg=="
+ "dts-resolver@2.1.1": {
+ "integrity": "sha512-3BiGFhB6mj5Kv+W2vdJseQUYW+SKVzAFJL6YNP6ursbrwy1fXHRotfHi3xLNxe4wZl/K8qbAFeCDjZLjzqxxRw=="
},
"empathic@2.0.0": {
"integrity": "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA=="
@@ -600,7 +603,7 @@
"resolve-pkg-maps@1.0.0": {
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="
},
- "rolldown-plugin-dts@0.13.14_rolldown@1.0.0-beta.34": {
+ "rolldown-plugin-dts@0.13.14_rolldown@1.0.0-beta.33": {
"integrity": "sha512-wjNhHZz9dlN6PTIXyizB6u/mAg1wEFMW9yw7imEVe3CxHSRnNHVyycIX0yDEOVJfDNISLPbkCIPEpFpizy5+PQ==",
"dependencies": [
"@babel/generator",
@@ -614,8 +617,8 @@
"rolldown"
]
},
- "rolldown@1.0.0-beta.34": {
- "integrity": "sha512-Wwh7EwalMzzX3Yy3VN58VEajeR2Si8+HDNMf706jPLIqU7CxneRW+dQVfznf5O0TWTnJyu4npelwg2bzTXB1Nw==",
+ "rolldown@1.0.0-beta.33": {
+ "integrity": "sha512-mgu118ZuRguC8unhPCbdZbyRbjQfEMiWqlojBA5aRIncBelRaBomnHNpGKYkYWeK7twRz5Cql30xgqqrA3Xelw==",
"dependencies": [
"@oxc-project/runtime",
"@oxc-project/types",
@@ -660,7 +663,7 @@
"picomatch"
]
},
- "tsdown@0.12.9_rolldown@1.0.0-beta.34": {
+ "tsdown@0.12.9_rolldown@1.0.0-beta.33": {
"integrity": "sha512-MfrXm9PIlT3saovtWKf/gCJJ/NQCdE0SiREkdNC+9Qy6UHhdeDPxnkFaBD7xttVUmgp0yUHtGirpoLB+OVLuLA==",
"dependencies": [
"ansis",
@@ -739,7 +742,7 @@
},
"workspace": {
"dependencies": [
- "jsr:@fedify/fedify@^1.8.8",
+ "jsr:@fedify/fedify@1.9.0-dev.1516+8f42bff1",
"jsr:@hongminhee/x-forwarded-fetch@0.2",
"jsr:@hono/hono@^4.8.2",
"jsr:@logtape/logtape@^1.0.4",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index d1fdce5..6c71565 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -7,8 +7,8 @@ settings:
catalogs:
default:
'@fedify/fedify':
- specifier: ^1.8.8
- version: 1.8.8
+ specifier: 1.9.0-dev.1516+8f42bff1
+ version: 1.9.0-dev.1516
'@js-temporal/polyfill':
specifier: ^0.5.1
version: 0.5.1
@@ -37,16 +37,16 @@ importers:
version: link:../packages/botkit-sqlite
'@fedify/fedify':
specifier: 'catalog:'
- version: 1.8.8(web-streams-polyfill@3.3.3)
+ version: 1.9.0-dev.1516(web-streams-polyfill@3.3.3)
'@fedify/postgres':
specifier: ^1.8.7
- version: 1.8.7(@fedify/fedify@1.8.8(web-streams-polyfill@3.3.3))(postgres@3.4.7)
+ version: 1.8.7(@fedify/fedify@1.9.0-dev.1516(web-streams-polyfill@3.3.3))(postgres@3.4.7)
'@fedify/redis':
specifier: ^1.8.7
- version: 1.8.7(@fedify/fedify@1.8.8(web-streams-polyfill@3.3.3))(ioredis@5.6.1)
+ version: 1.8.7(@fedify/fedify@1.9.0-dev.1516(web-streams-polyfill@3.3.3))(ioredis@5.6.1)
'@fedify/sqlite':
specifier: ^1.8.7
- version: 1.8.7(@fedify/fedify@1.8.8(web-streams-polyfill@3.3.3))
+ version: 1.8.7(@fedify/fedify@1.9.0-dev.1516(web-streams-polyfill@3.3.3))
'@js-temporal/polyfill':
specifier: 'catalog:'
version: 0.5.1
@@ -94,7 +94,7 @@ importers:
dependencies:
'@fedify/fedify':
specifier: 'catalog:'
- version: 1.8.8(web-streams-polyfill@3.3.3)
+ version: 1.9.0-dev.1516(web-streams-polyfill@3.3.3)
'@fedify/markdown-it-hashtag':
specifier: ^0.3.0
version: 0.3.0
@@ -146,7 +146,7 @@ importers:
version: link:../botkit
'@fedify/fedify':
specifier: 'catalog:'
- version: 1.8.8(web-streams-polyfill@3.3.3)
+ version: 1.9.0-dev.1516(web-streams-polyfill@3.3.3)
'@js-temporal/polyfill':
specifier: 'catalog:'
version: 0.5.1
@@ -446,8 +446,8 @@ packages:
resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==}
engines: {node: '>=14'}
- '@fedify/fedify@1.8.8':
- resolution: {integrity: sha512-1w5YfKbh8wNbcJ1s0Ttb2l3i4oiWmQ7z5sbKqQJMhBW6odaGGVgEO2bl6ZI5Tg0i5o/LK3ODOKLTlr8F1wibHA==}
+ '@fedify/fedify@1.9.0-dev.1516':
+ resolution: {integrity: sha512-nxXynvlgylYVwVgPmduIpjK99b5b/617qMQjfmtDVHNsdYXtjGqqipxVc+tz1uXwbsEzLO/z+o4jNo9lyF4BDQ==}
engines: {bun: '>=1.1.0', deno: '>=2.0.0', node: '>=22.0.0'}
'@fedify/markdown-it-hashtag@0.3.0':
@@ -2228,7 +2228,7 @@ snapshots:
'@fastify/busboy@2.1.1': {}
- '@fedify/fedify@1.8.8(web-streams-polyfill@3.3.3)':
+ '@fedify/fedify@1.9.0-dev.1516(web-streams-polyfill@3.3.3)':
dependencies:
'@cfworker/json-schema': 4.1.1
'@hugoalh/http-header-link': 1.0.3
@@ -2260,23 +2260,23 @@ snapshots:
dependencies:
markdown-it: 14.1.0
- '@fedify/postgres@1.8.7(@fedify/fedify@1.8.8(web-streams-polyfill@3.3.3))(postgres@3.4.7)':
+ '@fedify/postgres@1.8.7(@fedify/fedify@1.9.0-dev.1516(web-streams-polyfill@3.3.3))(postgres@3.4.7)':
dependencies:
- '@fedify/fedify': 1.8.8(web-streams-polyfill@3.3.3)
+ '@fedify/fedify': 1.9.0-dev.1516(web-streams-polyfill@3.3.3)
'@js-temporal/polyfill': 0.5.1
'@logtape/logtape': 1.0.0
postgres: 3.4.7
- '@fedify/redis@1.8.7(@fedify/fedify@1.8.8(web-streams-polyfill@3.3.3))(ioredis@5.6.1)':
+ '@fedify/redis@1.8.7(@fedify/fedify@1.9.0-dev.1516(web-streams-polyfill@3.3.3))(ioredis@5.6.1)':
dependencies:
- '@fedify/fedify': 1.8.8(web-streams-polyfill@3.3.3)
+ '@fedify/fedify': 1.9.0-dev.1516(web-streams-polyfill@3.3.3)
'@js-temporal/polyfill': 0.5.1
'@logtape/logtape': 1.0.0
ioredis: 5.6.1
- '@fedify/sqlite@1.8.7(@fedify/fedify@1.8.8(web-streams-polyfill@3.3.3))':
+ '@fedify/sqlite@1.8.7(@fedify/fedify@1.9.0-dev.1516(web-streams-polyfill@3.3.3))':
dependencies:
- '@fedify/fedify': 1.8.8(web-streams-polyfill@3.3.3)
+ '@fedify/fedify': 1.9.0-dev.1516(web-streams-polyfill@3.3.3)
'@logtape/logtape': 1.0.0
es-toolkit: 1.39.5
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index c08483b..3a2faf3 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -3,7 +3,7 @@ packages:
- docs
catalog:
- "@fedify/fedify": ^1.8.8
+ "@fedify/fedify": 1.9.0-dev.1516+8f42bff1
"@js-temporal/polyfill": ^0.5.1
"@logtape/logtape": ^1.0.4
hono: ^4.8.2