import { env } from "cloudflare:workers";
import { publicUrl } from "./events/emit";
import type { QueueMessage } from "./events/emit";
import { CATEGORY_INFO } from "~/lib/notification-categories";
import type { NotificationCategory } from "~/lib/notification-categories";
import { captureDevMail, devMailMode } from "./notify/dev-mail";
export type EmailQueueMessage = Extract<QueueMessage, { kind: "email.send" }>;
export type EmailContent = { subject: string; text: string; html: string; headers?: Record<string, string> };
type Action = { label: string; url: string };
/** Links appended to every notification email; `unsubscribeUrl` also drives the List-Unsubscribe headers. */
export type EmailFooter = { reason: string; manageUrl: string; unsubscribeUrl: string | null };
export type DigestEntry = { title: string; url: string };
const HTML_ESCAPES: Record<string, string> = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" };
const MAX_DETAIL_LENGTH = 500;
function escapeHtml(value: string): string {
return value.replace(/[&<>"']/g, (char) => HTML_ESCAPES[char] ?? char);
}
function forgeName(): string {
return env.FORGE_NAME || "gitfor";
}
function clip(value: string): string {
return value.length > MAX_DETAIL_LENGTH ? `${value.slice(0, MAX_DETAIL_LENGTH)}…` : value;
}
function footerHtml(footer: EmailFooter | null): string {
if (!footer) return "";
const unsubscribe = footer.unsubscribeUrl
? ` · <a href="${escapeHtml(footer.unsubscribeUrl)}" style="color:#a1a1aa">Unsubscribe</a>`
: "";
return `<hr style="border:0;border-top:1px solid #27272a;margin:24px 0 12px">
<p style="margin:0;color:#71717a;font-size:12px">${escapeHtml(footer.reason)}<br>
<a href="${escapeHtml(footer.manageUrl)}" style="color:#a1a1aa">Manage notification settings</a>${unsubscribe}</p>`;
}
type RenderInput = {