mirror of
https://github.com/juherr/kill-the-news.git
synced 2026-06-21 06:13:48 +00:00
refactor(domain): add FeedId, EmailAddress and Domain value objects
Encapsulate the email/domain/feed-id parsing that was scattered as ad-hoc
regexes and split("@") calls into three small immutable value objects under
src/domain/value-objects/. EmailParser.extractFeedId and generateFeedId now
delegate to FeedId; the sender policy, favicon domain extraction and the admin
SenderField parse through EmailAddress/Domain.
Left as-is on purpose: forwardemail's multi-address free-text extraction and the
admin allow/block list normaliser, which operate on mixed email-or-domain input
that the single-address value objects would reject.
Behaviour-preserving; adds unit tests for each value object.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* A normalised DNS domain (lowercased, no leading `@`, no trailing dots).
|
||||
* Accepts both bare (`example.com`) and allowlist-style (`@example.com`) input.
|
||||
*/
|
||||
export class Domain {
|
||||
private constructor(readonly value: string) {}
|
||||
|
||||
static parse(raw: string): Domain | null {
|
||||
const normalized = raw
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.replace(/^@+/, "")
|
||||
.replace(/\.+$/, "");
|
||||
return normalized ? new Domain(normalized) : null;
|
||||
}
|
||||
|
||||
matches(other: Domain): boolean {
|
||||
return this.value === other.value;
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user