refactor: extract url helpers, add EMAIL_DOMAIN support

- Add src/utils/urls.ts with baseUrl, feedRssUrl, feedAtomUrl, feedUrl,
  feedEmailAddress, feedTopicPattern
- Add optional EMAIL_DOMAIN env var so web domain and email domain can
  differ (e.g. demo.kill-the.news serves feeds, @kill-the.news receives mail)
- Replace all inline domain template literals with the new helpers
- Remove unused site_url/feed_url fields from FeedConfig
- Remove unused feedPath param from fetchFeedData
- Extract verifyCallback() to deduplicate verifyAndStoreSubscription /
  verifyAndDeleteSubscription

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Julien Herr
2026-05-22 22:38:29 +02:00
parent c64ceb4ee7
commit 7b2b98d693
15 changed files with 104 additions and 92 deletions
+6 -5
View File
@@ -2,6 +2,7 @@ import { Context } from "hono";
import { Env } from "../types";
import { generateAtomFeed } from "../utils/feed-generator";
import { fetchFeedData } from "../utils/feed-fetcher";
import { baseUrl, feedAtomUrl } from "../utils/urls";
export async function handle(c: Context<{ Bindings: Env }>): Promise<Response> {
try {
@@ -10,23 +11,23 @@ export async function handle(c: Context<{ Bindings: Env }>): Promise<Response> {
return new Response("Feed ID is required", { status: 400 });
}
const feedData = await fetchFeedData(feedId, c.env, "atom");
const feedData = await fetchFeedData(feedId, c.env);
if (!feedData) {
return new Response("Feed not found", { status: 404 });
}
const baseUrl = `https://${c.env.DOMAIN}`;
const base = baseUrl(c.env);
const selfUrl = new URL(c.req.url).origin + `/atom/${feedId}`;
const atomXml = generateAtomFeed(
feedData.feedConfig,
feedData.emails,
baseUrl,
base,
feedId,
selfUrl,
);
const linkHeader = [
`<${baseUrl}/hub>; rel="hub"`,
`<${baseUrl}/atom/${feedId}>; rel="self"`,
`<${base}/hub>; rel="hub"`,
`<${feedAtomUrl(feedId, c.env)}>; rel="self"`,
].join(", ");
return new Response(atomXml, {