From 7bf0f71f86fe0fb2fe3628ce04fc5fd6ec7851ae Mon Sep 17 00:00:00 2001 From: Julien Herr Date: Sun, 24 May 2026 00:46:56 +0200 Subject: [PATCH] refactor: split src into domain / application / infrastructure layers Replace the history-driven lib/ + utils/ split with DDD layers: - domain/: aggregate, repositories, value objects, pure parsers/format - application/: feed-service, email-processor, feed-fetcher, stats - infrastructure/: logging, auth, KV/R2 adapters, HTTP, framework glue Pure file relocation; imports updated mechanically. Behaviour unchanged. Co-Authored-By: Claude Opus 4.7 --- src/{lib => application}/email-processor.test.ts | 2 +- src/{lib => application}/email-processor.ts | 14 +++++++------- src/{utils => application}/feed-fetcher.ts | 0 src/{lib => application}/feed-service.ts | 8 ++++---- src/{utils => application}/stats.test.ts | 2 +- src/{utils => application}/stats.ts | 4 ++-- src/{utils => domain}/email-parser.test.ts | 0 src/{utils => domain}/email-parser.ts | 0 src/domain/feed-repository.ts | 2 +- src/{utils => domain}/format.ts | 0 src/domain/websub-subscription-repository.ts | 2 +- src/index.ts | 8 ++++---- src/{utils => infrastructure}/attachments.ts | 0 src/{lib => infrastructure}/auth.ts | 0 .../cloudflare-email.test.ts | 0 src/{lib => infrastructure}/cloudflare-email.ts | 4 ++-- .../favicon-fetcher.test.ts | 0 src/{utils => infrastructure}/favicon-fetcher.ts | 2 +- .../feed-generator.test.ts | 0 src/{utils => infrastructure}/feed-generator.ts | 0 src/{lib => infrastructure}/forwardemail.ts | 10 +++++++--- .../html-processor.test.ts | 0 src/{utils => infrastructure}/html-processor.ts | 0 src/{lib => infrastructure}/logger.ts | 0 src/{utils => infrastructure}/unsubscribe.test.ts | 2 +- src/{utils => infrastructure}/unsubscribe.ts | 4 ++-- src/{utils => infrastructure}/urls.ts | 0 src/{utils => infrastructure}/websub.test.ts | 0 src/{utils => infrastructure}/websub.ts | 0 src/{utils => infrastructure}/worker.ts | 0 src/routes/admin.test.ts | 2 +- src/routes/admin.tsx | 12 ++++++++---- src/routes/admin/emails.tsx | 10 +++++++--- src/routes/admin/feeds.tsx | 14 +++++++------- src/routes/admin/helpers.ts | 4 ++-- src/routes/api/index.ts | 12 ++++++++---- src/routes/atom.ts | 6 +++--- src/routes/entries.ts | 4 ++-- src/routes/favicon.ts | 5 ++++- src/routes/files.ts | 2 +- src/routes/home.tsx | 4 ++-- src/routes/hub.ts | 6 +++--- src/routes/inbound.test.ts | 2 +- src/routes/inbound.ts | 5 ++++- src/routes/rss.ts | 6 +++--- 45 files changed, 90 insertions(+), 68 deletions(-) rename src/{lib => application}/email-processor.test.ts (99%) rename src/{lib => application}/email-processor.ts (93%) rename src/{utils => application}/feed-fetcher.ts (100%) rename src/{lib => application}/feed-service.ts (95%) rename src/{utils => application}/stats.test.ts (99%) rename src/{utils => application}/stats.ts (97%) rename src/{utils => domain}/email-parser.test.ts (100%) rename src/{utils => domain}/email-parser.ts (100%) rename src/{utils => domain}/format.ts (100%) rename src/{utils => infrastructure}/attachments.ts (100%) rename src/{lib => infrastructure}/auth.ts (100%) rename src/{lib => infrastructure}/cloudflare-email.test.ts (100%) rename src/{lib => infrastructure}/cloudflare-email.ts (91%) rename src/{utils => infrastructure}/favicon-fetcher.test.ts (100%) rename src/{utils => infrastructure}/favicon-fetcher.ts (98%) rename src/{utils => infrastructure}/feed-generator.test.ts (100%) rename src/{utils => infrastructure}/feed-generator.ts (100%) rename src/{lib => infrastructure}/forwardemail.ts (94%) rename src/{utils => infrastructure}/html-processor.test.ts (100%) rename src/{utils => infrastructure}/html-processor.ts (100%) rename src/{lib => infrastructure}/logger.ts (100%) rename src/{utils => infrastructure}/unsubscribe.test.ts (99%) rename src/{utils => infrastructure}/unsubscribe.ts (96%) rename src/{utils => infrastructure}/urls.ts (100%) rename src/{utils => infrastructure}/websub.test.ts (100%) rename src/{utils => infrastructure}/websub.ts (100%) rename src/{utils => infrastructure}/worker.ts (100%) diff --git a/src/lib/email-processor.test.ts b/src/application/email-processor.test.ts similarity index 99% rename from src/lib/email-processor.test.ts rename to src/application/email-processor.test.ts index 23dec47..fce48ff 100644 --- a/src/lib/email-processor.test.ts +++ b/src/application/email-processor.test.ts @@ -6,7 +6,7 @@ import { ProcessEmailInput, RawAttachment, } from "./email-processor"; -import { getCounters } from "../utils/stats"; +import { getCounters } from "../application/stats"; const iconKey = (domain: string) => `icon:${domain}`; diff --git a/src/lib/email-processor.ts b/src/application/email-processor.ts similarity index 93% rename from src/lib/email-processor.ts rename to src/application/email-processor.ts index 462d136..ec390eb 100644 --- a/src/lib/email-processor.ts +++ b/src/application/email-processor.ts @@ -1,17 +1,17 @@ -import { EmailParser } from "../utils/email-parser"; +import { EmailParser } from "../domain/email-parser"; import { AttachmentData, EmailMetadata, Env } from "../types"; -import { notifySubscribers } from "../utils/websub"; -import { bumpCounters } from "../utils/stats"; +import { notifySubscribers } from "../infrastructure/websub"; +import { bumpCounters } from "../application/stats"; import { cacheFaviconForDomain, extractEmailDomain, -} from "../utils/favicon-fetcher"; -import { parseOneClickUnsubscribe } from "../utils/unsubscribe"; -import { getAttachmentBucket } from "../utils/attachments"; +} from "../infrastructure/favicon-fetcher"; +import { parseOneClickUnsubscribe } from "../infrastructure/unsubscribe"; +import { getAttachmentBucket } from "../infrastructure/attachments"; import { FeedRepository } from "../domain/feed-repository"; import { Feed } from "../domain/feed.aggregate"; import { FeedId } from "../domain/value-objects/feed-id"; -import { logger } from "./logger"; +import { logger } from "../infrastructure/logger"; import { FEED_MAX_BYTES } from "../config/constants"; export interface RawAttachment { diff --git a/src/utils/feed-fetcher.ts b/src/application/feed-fetcher.ts similarity index 100% rename from src/utils/feed-fetcher.ts rename to src/application/feed-fetcher.ts diff --git a/src/lib/feed-service.ts b/src/application/feed-service.ts similarity index 95% rename from src/lib/feed-service.ts rename to src/application/feed-service.ts index 9bc18d7..24e3162 100644 --- a/src/lib/feed-service.ts +++ b/src/application/feed-service.ts @@ -1,9 +1,9 @@ import { Context } from "hono"; import { Env, FeedConfig } from "../types"; -import { bumpCounters } from "../utils/stats"; -import { waitUntilSafe } from "../utils/worker"; -import { sendUnsubscribes } from "../utils/unsubscribe"; -import { getAttachmentBucket } from "../utils/attachments"; +import { bumpCounters } from "../application/stats"; +import { waitUntilSafe } from "../infrastructure/worker"; +import { sendUnsubscribes } from "../infrastructure/unsubscribe"; +import { getAttachmentBucket } from "../infrastructure/attachments"; import { FeedRepository } from "../domain/feed-repository"; import { FeedId } from "../domain/value-objects/feed-id"; import { diff --git a/src/utils/stats.test.ts b/src/application/stats.test.ts similarity index 99% rename from src/utils/stats.test.ts rename to src/application/stats.test.ts index eacc5aa..47b35d8 100644 --- a/src/utils/stats.test.ts +++ b/src/application/stats.test.ts @@ -9,7 +9,7 @@ import { scanKvUsage, setStorageSnapshot, } from "./stats"; -import { getAttachmentBucket } from "./attachments"; +import { getAttachmentBucket } from "../infrastructure/attachments"; import { STATS_KEY, FEEDS_LIST_KEY } from "../config/constants"; import { Env } from "../types"; diff --git a/src/utils/stats.ts b/src/application/stats.ts similarity index 97% rename from src/utils/stats.ts rename to src/application/stats.ts index aa04384..43bb999 100644 --- a/src/utils/stats.ts +++ b/src/application/stats.ts @@ -1,10 +1,10 @@ import { Counters, Env, StatsResponse } from "../types"; -import { logger } from "../lib/logger"; +import { logger } from "../infrastructure/logger"; import { FeedRepository } from "../domain/feed-repository"; import { CountersRepository } from "../domain/counters-repository"; import { WebSubSubscriptionRepository } from "../domain/websub-subscription-repository"; import { FeedId } from "../domain/value-objects/feed-id"; -import { getAttachmentBucket } from "./attachments"; +import { getAttachmentBucket } from "../infrastructure/attachments"; const EMPTY_COUNTERS: Counters = { feeds_created: 0, diff --git a/src/utils/email-parser.test.ts b/src/domain/email-parser.test.ts similarity index 100% rename from src/utils/email-parser.test.ts rename to src/domain/email-parser.test.ts diff --git a/src/utils/email-parser.ts b/src/domain/email-parser.ts similarity index 100% rename from src/utils/email-parser.ts rename to src/domain/email-parser.ts diff --git a/src/domain/feed-repository.ts b/src/domain/feed-repository.ts index 5f51b96..24ecb62 100644 --- a/src/domain/feed-repository.ts +++ b/src/domain/feed-repository.ts @@ -10,7 +10,7 @@ import { FEEDS_LIST_KEY } from "../config/constants"; import { feedKeys } from "./feed-keys"; import { Feed } from "./feed.aggregate"; import { FeedId } from "./value-objects/feed-id"; -import { logger } from "../lib/logger"; +import { logger } from "../infrastructure/logger"; /** * Single source of truth for KV access to the Feed aggregate. The key schema diff --git a/src/utils/format.ts b/src/domain/format.ts similarity index 100% rename from src/utils/format.ts rename to src/domain/format.ts diff --git a/src/domain/websub-subscription-repository.ts b/src/domain/websub-subscription-repository.ts index 622af06..f73df15 100644 --- a/src/domain/websub-subscription-repository.ts +++ b/src/domain/websub-subscription-repository.ts @@ -1,6 +1,6 @@ import { Env, WebSubSubscription } from "../types"; import { feedKeys } from "./feed-keys"; -import { logger } from "../lib/logger"; +import { logger } from "../infrastructure/logger"; /** * KV access for per-feed WebSub subscriber lists (`websub:subs:`). diff --git a/src/index.ts b/src/index.ts index 9e71e03..0d0d7a4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,9 +10,9 @@ import { handle as handleHome } from "./routes/home"; import { handle as handleFavicon, handleFeedFavicon } from "./routes/favicon"; import { hubRouter } from "./routes/hub"; import { apiApp } from "./routes/api"; -import { handleCloudflareEmail } from "./lib/cloudflare-email"; +import { handleCloudflareEmail } from "./infrastructure/cloudflare-email"; import { Env } from "./types"; -import { logger } from "./lib/logger"; +import { logger } from "./infrastructure/logger"; import { FeedRepository } from "./domain/feed-repository"; import { purgeExpiredFeeds } from "./routes/admin/helpers"; import { @@ -20,8 +20,8 @@ import { scanR2Usage, scanKvUsage, setStorageSnapshot, -} from "./utils/stats"; -import { getAttachmentBucket } from "./utils/attachments"; +} from "./application/stats"; +import { getAttachmentBucket } from "./infrastructure/attachments"; import { FORWARD_EMAIL_IPS_CACHE_TTL_MS } from "./config/constants"; type AppEnv = { Bindings: Env }; diff --git a/src/utils/attachments.ts b/src/infrastructure/attachments.ts similarity index 100% rename from src/utils/attachments.ts rename to src/infrastructure/attachments.ts diff --git a/src/lib/auth.ts b/src/infrastructure/auth.ts similarity index 100% rename from src/lib/auth.ts rename to src/infrastructure/auth.ts diff --git a/src/lib/cloudflare-email.test.ts b/src/infrastructure/cloudflare-email.test.ts similarity index 100% rename from src/lib/cloudflare-email.test.ts rename to src/infrastructure/cloudflare-email.test.ts diff --git a/src/lib/cloudflare-email.ts b/src/infrastructure/cloudflare-email.ts similarity index 91% rename from src/lib/cloudflare-email.ts rename to src/infrastructure/cloudflare-email.ts index f42afc2..6f814a4 100644 --- a/src/lib/cloudflare-email.ts +++ b/src/infrastructure/cloudflare-email.ts @@ -1,7 +1,7 @@ import PostalMime from "postal-mime"; import { Env } from "../types"; -import { processEmail, RawAttachment } from "./email-processor"; -import { normalizeCid } from "../utils/html-processor"; +import { processEmail, RawAttachment } from "../application/email-processor"; +import { normalizeCid } from "../infrastructure/html-processor"; import { logger } from "./logger"; export async function handleCloudflareEmail( diff --git a/src/utils/favicon-fetcher.test.ts b/src/infrastructure/favicon-fetcher.test.ts similarity index 100% rename from src/utils/favicon-fetcher.test.ts rename to src/infrastructure/favicon-fetcher.test.ts diff --git a/src/utils/favicon-fetcher.ts b/src/infrastructure/favicon-fetcher.ts similarity index 98% rename from src/utils/favicon-fetcher.ts rename to src/infrastructure/favicon-fetcher.ts index 19e7ebd..463bcb4 100644 --- a/src/utils/favicon-fetcher.ts +++ b/src/infrastructure/favicon-fetcher.ts @@ -6,7 +6,7 @@ import { } from "../config/constants"; import { IconRepository } from "../domain/icon-repository"; import { EmailAddress } from "../domain/value-objects/email-address"; -import { logger } from "../lib/logger"; +import { logger } from "../infrastructure/logger"; interface IconRecord { data: string | null; // base64 icon bytes, or null for a negative cache entry diff --git a/src/utils/feed-generator.test.ts b/src/infrastructure/feed-generator.test.ts similarity index 100% rename from src/utils/feed-generator.test.ts rename to src/infrastructure/feed-generator.test.ts diff --git a/src/utils/feed-generator.ts b/src/infrastructure/feed-generator.ts similarity index 100% rename from src/utils/feed-generator.ts rename to src/infrastructure/feed-generator.ts diff --git a/src/lib/forwardemail.ts b/src/infrastructure/forwardemail.ts similarity index 94% rename from src/lib/forwardemail.ts rename to src/infrastructure/forwardemail.ts index 6ab67d6..0049e9c 100644 --- a/src/lib/forwardemail.ts +++ b/src/infrastructure/forwardemail.ts @@ -1,7 +1,11 @@ -import { EmailParser } from "../utils/email-parser"; +import { EmailParser } from "../domain/email-parser"; import { Env } from "../types"; -import { processEmail, IngestResult, RawAttachment } from "./email-processor"; -import { normalizeCid } from "../utils/html-processor"; +import { + processEmail, + IngestResult, + RawAttachment, +} from "../application/email-processor"; +import { normalizeCid } from "../infrastructure/html-processor"; /** Map an ingestion result to the HTTP response ForwardEmail expects. */ export function ingestResultToResponse(result: IngestResult): Response { diff --git a/src/utils/html-processor.test.ts b/src/infrastructure/html-processor.test.ts similarity index 100% rename from src/utils/html-processor.test.ts rename to src/infrastructure/html-processor.test.ts diff --git a/src/utils/html-processor.ts b/src/infrastructure/html-processor.ts similarity index 100% rename from src/utils/html-processor.ts rename to src/infrastructure/html-processor.ts diff --git a/src/lib/logger.ts b/src/infrastructure/logger.ts similarity index 100% rename from src/lib/logger.ts rename to src/infrastructure/logger.ts diff --git a/src/utils/unsubscribe.test.ts b/src/infrastructure/unsubscribe.test.ts similarity index 99% rename from src/utils/unsubscribe.test.ts rename to src/infrastructure/unsubscribe.test.ts index 78f8634..36ebc4d 100644 --- a/src/utils/unsubscribe.test.ts +++ b/src/infrastructure/unsubscribe.test.ts @@ -6,7 +6,7 @@ import { sendOneClickUnsubscribe, sendUnsubscribes, } from "./unsubscribe"; -import { getCounters } from "./stats"; +import { getCounters } from "../application/stats"; import type { Env } from "../types"; const POST_HEADER = "List-Unsubscribe=One-Click"; diff --git a/src/utils/unsubscribe.ts b/src/infrastructure/unsubscribe.ts similarity index 96% rename from src/utils/unsubscribe.ts rename to src/infrastructure/unsubscribe.ts index 7a6ed05..f865635 100644 --- a/src/utils/unsubscribe.ts +++ b/src/infrastructure/unsubscribe.ts @@ -1,7 +1,7 @@ import { Env } from "../types"; import { UNSUBSCRIBE_TIMEOUT_MS } from "../config/constants"; -import { bumpCounters } from "./stats"; -import { logger } from "../lib/logger"; +import { bumpCounters } from "../application/stats"; +import { logger } from "../infrastructure/logger"; /** * Extract a one-click unsubscribe URL from a stored email's headers per diff --git a/src/utils/urls.ts b/src/infrastructure/urls.ts similarity index 100% rename from src/utils/urls.ts rename to src/infrastructure/urls.ts diff --git a/src/utils/websub.test.ts b/src/infrastructure/websub.test.ts similarity index 100% rename from src/utils/websub.test.ts rename to src/infrastructure/websub.test.ts diff --git a/src/utils/websub.ts b/src/infrastructure/websub.ts similarity index 100% rename from src/utils/websub.ts rename to src/infrastructure/websub.ts diff --git a/src/utils/worker.ts b/src/infrastructure/worker.ts similarity index 100% rename from src/utils/worker.ts rename to src/infrastructure/worker.ts diff --git a/src/routes/admin.test.ts b/src/routes/admin.test.ts index 789888a..36a1fdc 100644 --- a/src/routes/admin.test.ts +++ b/src/routes/admin.test.ts @@ -3,7 +3,7 @@ import { http, HttpResponse } from "msw"; import { Hono } from "hono"; import app from "./admin"; import { createMockEnv, server } from "../test/setup"; -import { getCounters } from "../utils/stats"; +import { getCounters } from "../application/stats"; import { Env } from "../types"; describe("Admin Routes", () => { diff --git a/src/routes/admin.tsx b/src/routes/admin.tsx index 2d5e9d2..d7c200e 100644 --- a/src/routes/admin.tsx +++ b/src/routes/admin.tsx @@ -5,12 +5,16 @@ import { z } from "zod"; import { Env } from "../types"; import { csrf } from "hono/csrf"; import { ADMIN_COOKIE_MAX_AGE } from "../config/constants"; -import { logger } from "../lib/logger"; -import { timingSafeEqual, checkProxyAuth } from "../lib/auth"; +import { logger } from "../infrastructure/logger"; +import { timingSafeEqual, checkProxyAuth } from "../infrastructure/auth"; import { Layout, clampText } from "./admin/ui"; import { FeedRepository } from "../domain/feed-repository"; -import { renameFeed } from "../lib/feed-service"; -import { feedRssUrl, feedAtomUrl, feedEmailAddress } from "../utils/urls"; +import { renameFeed } from "../application/feed-service"; +import { + feedRssUrl, + feedAtomUrl, + feedEmailAddress, +} from "../infrastructure/urls"; import { feedsRouter } from "./admin/feeds"; import { emailsRouter } from "./admin/emails"; import { dashboardScript } from "../scripts/generated/dashboard"; diff --git a/src/routes/admin/emails.tsx b/src/routes/admin/emails.tsx index c5ba2cc..b30665a 100644 --- a/src/routes/admin/emails.tsx +++ b/src/routes/admin/emails.tsx @@ -1,6 +1,6 @@ import { Hono } from "hono"; import { Env, EmailMetadata } from "../../types"; -import { logger } from "../../lib/logger"; +import { logger } from "../../infrastructure/logger"; import { Layout, clampText } from "./ui"; import { deleteAttachmentsForEmails, @@ -8,8 +8,12 @@ import { } from "./helpers"; import { FeedRepository } from "../../domain/feed-repository"; import { FeedId } from "../../domain/value-objects/feed-id"; -import { feedRssUrl, feedAtomUrl, feedEmailAddress } from "../../utils/urls"; -import { formatBytes } from "../../utils/format"; +import { + feedRssUrl, + feedAtomUrl, + feedEmailAddress, +} from "../../infrastructure/urls"; +import { formatBytes } from "../../domain/format"; import { EmailAddress } from "../../domain/value-objects/email-address"; import { emailsPageScript } from "../../scripts/generated/emails-page"; diff --git a/src/routes/admin/feeds.tsx b/src/routes/admin/feeds.tsx index 3e2bc23..e437c25 100644 --- a/src/routes/admin/feeds.tsx +++ b/src/routes/admin/feeds.tsx @@ -1,12 +1,12 @@ import { Hono } from "hono"; import { z } from "zod"; import { Env } from "../../types"; -import { bumpCounters } from "../../utils/stats"; -import { waitUntilSafe } from "../../utils/worker"; -import { feedRssUrl, feedEmailAddress } from "../../utils/urls"; -import { logger } from "../../lib/logger"; -import { sendUnsubscribes } from "../../utils/unsubscribe"; -import { getAttachmentBucket } from "../../utils/attachments"; +import { bumpCounters } from "../../application/stats"; +import { waitUntilSafe } from "../../infrastructure/worker"; +import { feedRssUrl, feedEmailAddress } from "../../infrastructure/urls"; +import { logger } from "../../infrastructure/logger"; +import { sendUnsubscribes } from "../../infrastructure/unsubscribe"; +import { getAttachmentBucket } from "../../infrastructure/attachments"; import { Layout } from "./ui"; import { purgeFeedKeysStep, collectUnsubscribeUrls } from "./helpers"; import { FeedRepository } from "../../domain/feed-repository"; @@ -16,7 +16,7 @@ import { editFeed, deleteFeedRecord, deleteFeedFastDetailed, -} from "../../lib/feed-service"; +} from "../../application/feed-service"; type AppEnv = { Bindings: Env }; diff --git a/src/routes/admin/helpers.ts b/src/routes/admin/helpers.ts index bbab567..fbbca08 100644 --- a/src/routes/admin/helpers.ts +++ b/src/routes/admin/helpers.ts @@ -1,6 +1,6 @@ import { EmailData, EmailMetadata, Env } from "../../types"; -import { logger } from "../../lib/logger"; -import { getAttachmentBucket } from "../../utils/attachments"; +import { logger } from "../../infrastructure/logger"; +import { getAttachmentBucket } from "../../infrastructure/attachments"; import { FeedRepository } from "../../domain/feed-repository"; import { FeedId } from "../../domain/value-objects/feed-id"; diff --git a/src/routes/api/index.ts b/src/routes/api/index.ts index 1ee1a34..6ece629 100644 --- a/src/routes/api/index.ts +++ b/src/routes/api/index.ts @@ -2,17 +2,21 @@ import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi"; import { cors } from "hono/cors"; import { Scalar } from "@scalar/hono-api-reference"; import { Env, FeedConfig } from "../../types"; -import { apiAuthMiddleware } from "../../lib/auth"; +import { apiAuthMiddleware } from "../../infrastructure/auth"; import { createFeedRecord, editFeed, deleteFeedRecord, -} from "../../lib/feed-service"; +} from "../../application/feed-service"; import { deleteAttachmentsForEmails } from "../admin/helpers"; import { FeedRepository } from "../../domain/feed-repository"; import { FeedId } from "../../domain/value-objects/feed-id"; -import { getStats } from "../../utils/stats"; -import { feedEmailAddress, feedRssUrl, feedAtomUrl } from "../../utils/urls"; +import { getStats } from "../../application/stats"; +import { + feedEmailAddress, + feedRssUrl, + feedAtomUrl, +} from "../../infrastructure/urls"; import { ErrorSchema, FeedIdParam, diff --git a/src/routes/atom.ts b/src/routes/atom.ts index eae26d1..62e680b 100644 --- a/src/routes/atom.ts +++ b/src/routes/atom.ts @@ -1,8 +1,8 @@ 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"; +import { generateAtomFeed } from "../infrastructure/feed-generator"; +import { fetchFeedData } from "../application/feed-fetcher"; +import { baseUrl, feedAtomUrl } from "../infrastructure/urls"; import { isExpired } from "../domain/feed"; export async function handle(c: Context<{ Bindings: Env }>): Promise { diff --git a/src/routes/entries.ts b/src/routes/entries.ts index 2db4302..982f22c 100644 --- a/src/routes/entries.ts +++ b/src/routes/entries.ts @@ -1,8 +1,8 @@ import { Context } from "hono"; import { html, raw } from "hono/html"; import { Env } from "../types"; -import { processEmailContent } from "../utils/html-processor"; -import { formatBytes } from "../utils/format"; +import { processEmailContent } from "../infrastructure/html-processor"; +import { formatBytes } from "../domain/format"; import { FeedRepository } from "../domain/feed-repository"; import { FeedId } from "../domain/value-objects/feed-id"; import { isExpired } from "../domain/feed"; diff --git a/src/routes/favicon.ts b/src/routes/favicon.ts index 6dbc369..e28bb29 100644 --- a/src/routes/favicon.ts +++ b/src/routes/favicon.ts @@ -2,7 +2,10 @@ import { Context } from "hono"; import { Env } from "../types"; import { FeedRepository } from "../domain/feed-repository"; import { FeedId } from "../domain/value-objects/feed-id"; -import { cacheFaviconForDomain, getCachedIcon } from "../utils/favicon-fetcher"; +import { + cacheFaviconForDomain, + getCachedIcon, +} from "../infrastructure/favicon-fetcher"; export const FAVICON_PATH = "/favicon.svg"; diff --git a/src/routes/files.ts b/src/routes/files.ts index 16f02d9..e3b7db4 100644 --- a/src/routes/files.ts +++ b/src/routes/files.ts @@ -1,6 +1,6 @@ import { Context } from "hono"; import { Env } from "../types"; -import { getAttachmentBucket } from "../utils/attachments"; +import { getAttachmentBucket } from "../infrastructure/attachments"; export async function handle(c: Context<{ Bindings: Env }>): Promise { const bucket = getAttachmentBucket(c.env); diff --git a/src/routes/home.tsx b/src/routes/home.tsx index 5dd862a..c65702d 100644 --- a/src/routes/home.tsx +++ b/src/routes/home.tsx @@ -1,7 +1,7 @@ import { Context } from "hono"; import { Env } from "../types"; -import { getStats } from "../utils/stats"; -import { formatBytes } from "../utils/format"; +import { getStats } from "../application/stats"; +import { formatBytes } from "../domain/format"; import { R2_FREE_TIER_BYTES, KV_FREE_TIER_BYTES } from "../config/constants"; import { Layout } from "./admin/ui"; diff --git a/src/routes/hub.ts b/src/routes/hub.ts index 7f5429f..bbe3597 100644 --- a/src/routes/hub.ts +++ b/src/routes/hub.ts @@ -3,10 +3,10 @@ import { Env } from "../types"; import { verifyAndStoreSubscription, verifyAndDeleteSubscription, -} from "../utils/websub"; -import { waitUntilSafe } from "../utils/worker"; +} from "../infrastructure/websub"; +import { waitUntilSafe } from "../infrastructure/worker"; import { DEFAULT_LEASE_SECONDS, MAX_LEASE_SECONDS } from "../config/constants"; -import { feedTopicPattern } from "../utils/urls"; +import { feedTopicPattern } from "../infrastructure/urls"; import { FeedRepository } from "../domain/feed-repository"; import { FeedId } from "../domain/value-objects/feed-id"; diff --git a/src/routes/inbound.test.ts b/src/routes/inbound.test.ts index 7cc7d33..75a72af 100644 --- a/src/routes/inbound.test.ts +++ b/src/routes/inbound.test.ts @@ -3,7 +3,7 @@ import { http, HttpResponse } from "msw"; import worker from "../index"; import { server, createMockEnv, MockR2 } from "../test/setup"; import type { Env } from "../types"; -import type { ForwardEmailPayload } from "../lib/forwardemail"; +import type { ForwardEmailPayload } from "../infrastructure/forwardemail"; const AUTHORIZED_IP = "138.197.213.185"; // first fallback IP const DOMAIN = "test.getmynews.app"; diff --git a/src/routes/inbound.ts b/src/routes/inbound.ts index cd647d6..05b2df2 100644 --- a/src/routes/inbound.ts +++ b/src/routes/inbound.ts @@ -1,6 +1,9 @@ import { Context } from "hono"; import { Env } from "../types"; -import { ForwardEmailPayload, handleForwardEmail } from "../lib/forwardemail"; +import { + ForwardEmailPayload, + handleForwardEmail, +} from "../infrastructure/forwardemail"; export async function handle(c: Context<{ Bindings: Env }>): Promise { try { diff --git a/src/routes/rss.ts b/src/routes/rss.ts index df85eba..d39eeb3 100644 --- a/src/routes/rss.ts +++ b/src/routes/rss.ts @@ -1,8 +1,8 @@ import { Context } from "hono"; import { Env } from "../types"; -import { generateRssFeed } from "../utils/feed-generator"; -import { fetchFeedData } from "../utils/feed-fetcher"; -import { baseUrl, feedRssUrl } from "../utils/urls"; +import { generateRssFeed } from "../infrastructure/feed-generator"; +import { fetchFeedData } from "../application/feed-fetcher"; +import { baseUrl, feedRssUrl } from "../infrastructure/urls"; import { isExpired } from "../domain/feed"; export async function handle(c: Context<{ Bindings: Env }>): Promise {