refactor: simplify quick-win code after review

- Make feedId required in generateRssFeed (removes dead /emails/ fallback)
- Hoist loop-invariant conditional and remove intermediate variable
- Extract normalizeAllowedSenders() so JSON and form paths share same logic
- Move escapeHtml to src/utils/html.ts for reuse by admin.ts
- Parallelize the two independent KV puts in feed creation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Julien Herr
2026-05-20 23:55:17 +02:00
parent e140b433d8
commit 5308544672
4 changed files with 21 additions and 34 deletions
+10 -12
View File
@@ -41,11 +41,12 @@ function waitUntilSafe(c: Context, promise: Promise<unknown>) {
}
}
function normalizeAllowedSenders(senders: string[]): string[] {
return senders.map((s) => s.trim().toLowerCase()).filter(Boolean);
}
function parseAllowedSenders(rawAllowedSenders: string): string[] {
return rawAllowedSenders
.split(/[\n,]+/)
.map((value) => value.trim().toLowerCase())
.filter(Boolean);
return normalizeAllowedSenders(rawAllowedSenders.split(/[\n,]+/));
}
function clampText(value: string, maxLen: number): string {
@@ -1580,7 +1581,7 @@ app.post("/feeds/create", async (c) => {
language = String(body.language ?? "en");
view = "list";
allowedSenders = Array.isArray(body.allowedSenders)
? (body.allowedSenders as unknown[]).map(String).map((s) => s.trim().toLowerCase()).filter(Boolean)
? normalizeAllowedSenders((body.allowedSenders as unknown[]).map(String))
: [];
} else {
const formData = await c.req.formData();
@@ -1621,14 +1622,11 @@ app.post("/feeds/create", async (c) => {
emails: [],
};
// Store feed configuration and metadata
await emailStorage.put(`feed:${feedId}:config`, JSON.stringify(feedConfig));
await emailStorage.put(
`feed:${feedId}:metadata`,
JSON.stringify(feedMetadata),
);
await Promise.all([
emailStorage.put(`feed:${feedId}:config`, JSON.stringify(feedConfig)),
emailStorage.put(`feed:${feedId}:metadata`, JSON.stringify(feedMetadata)),
]);
// Add feed to the list of all feeds
await addFeedToList(
emailStorage,
feedId,
+1 -8
View File
@@ -1,13 +1,6 @@
import { Context } from "hono";
import { Env, FeedMetadata, EmailData } from "../types";
function escapeHtml(str: string): string {
return str
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;");
}
import { escapeHtml } from "../utils/html";
export async function handle(c: Context): Promise<Response> {
const env = c.env as unknown as Env;
+3 -14
View File
@@ -13,16 +13,12 @@ function parseFromAddress(from: string): { name: string; email?: string } {
return { name: from.trim() };
}
/**
* Generate an RSS feed from a list of emails
*/
export function generateRssFeed(
feedConfig: FeedConfig,
emails: EmailData[],
baseUrl: string,
feedId?: string,
feedId: string,
): string {
// Create a new feed
const feed = new Feed({
title: feedConfig.title,
description: feedConfig.description || "",
@@ -43,25 +39,18 @@ export function generateRssFeed(
: undefined,
});
// Add each email as a feed item
for (const email of emails) {
const date = new Date(email.receivedAt);
const uniqueId = `${email.receivedAt}-${Buffer.from(email.subject).toString("base64").substring(0, 10)}`;
const entryLink = feedId
? `${baseUrl}/entries/${feedId}/${email.receivedAt}`
: `${baseUrl}/emails/${uniqueId}`;
feed.addItem({
title: email.subject,
id: uniqueId,
link: entryLink,
link: `${baseUrl}/entries/${feedId}/${email.receivedAt}`,
description: email.content,
content: email.content,
author: [parseFromAddress(email.from)],
date: date,
date: new Date(email.receivedAt),
});
}
// Return the RSS feed as XML
return feed.rss2();
}
+7
View File
@@ -0,0 +1,7 @@
export function escapeHtml(str: string): string {
return str
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;");
}