Skip to content

Commit 23e0a25

Browse files
committed
fix(core): parse favicon host via tldts
Use tldts domain parsing in favicon resolution and add its dependency.
1 parent 62dd741 commit 23e0a25

3 files changed

Lines changed: 19 additions & 58 deletions

File tree

bun.lock

Lines changed: 12 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/sources/core/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
"@executor/codemode-core": "workspace:*",
1616
"@executor/ir": "workspace:*",
1717
"@modelcontextprotocol/sdk": "^1.26.0",
18-
"effect": "catalog:"
18+
"effect": "catalog:",
19+
"tldts": "^7.0.27"
1920
},
2021
"devDependencies": {
2122
"@types/node": "catalog:",

packages/sources/core/src/favicon.ts

Lines changed: 5 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,4 @@
1-
const COMMON_COMPOUND_SUFFIXES = new Set([
2-
"ac.uk",
3-
"co.in",
4-
"co.jp",
5-
"co.nz",
6-
"co.uk",
7-
"com.au",
8-
"com.br",
9-
"com.mx",
10-
"net.au",
11-
"org.au",
12-
"org.uk",
13-
]);
1+
import { parse as parseDomain } from "tldts";
142

153
const RAW_HOSTS = new Set([
164
"cdn.jsdelivr.net",
@@ -19,49 +7,13 @@ const RAW_HOSTS = new Set([
197
"unpkg.com",
208
]);
219

22-
function trimOrNull(value: string | null | undefined): string | null {
23-
if (value == null) {
24-
return null;
25-
}
26-
27-
const trimmed = value.trim();
28-
return trimmed.length > 0 ? trimmed : null;
29-
}
30-
31-
function isIpv4Address(value: string): boolean {
32-
return /^\d{1,3}(?:\.\d{1,3}){3}$/.test(value);
33-
}
34-
35-
export function getRegistrableDomain(hostname: string): string | null {
36-
const normalized = hostname.trim().toLowerCase().replace(/^\.+|\.+$/g, "");
37-
if (!normalized) {
38-
return null;
39-
}
40-
41-
if (normalized === "localhost" || isIpv4Address(normalized)) {
42-
return normalized;
43-
}
44-
45-
const parts = normalized.split(".").filter((part) => part.length > 0);
46-
if (parts.length < 2) {
47-
return null;
48-
}
49-
50-
const suffix = parts.slice(-2).join(".");
51-
if (parts.length >= 3 && COMMON_COMPOUND_SUFFIXES.has(suffix)) {
52-
return parts.slice(-3).join(".");
53-
}
54-
55-
return parts.slice(-2).join(".");
56-
}
57-
5810
export function getFaviconUrlForRemoteUrl(
5911
value: string | null | undefined,
6012
options: {
6113
allowRawHosts?: boolean;
6214
} = {},
6315
): string | null {
64-
const trimmed = trimOrNull(value);
16+
const trimmed = value?.trim();
6517
if (!trimmed) {
6618
return null;
6719
}
@@ -76,10 +28,9 @@ export function getFaviconUrlForRemoteUrl(
7628
return null;
7729
}
7830

79-
const domain = getRegistrableDomain(url.hostname);
80-
return domain
81-
? `https://www.google.com/s2/favicons?domain=${encodeURIComponent(domain)}&sz=32`
82-
: null;
31+
const parsed = parseDomain(url.hostname);
32+
const domain = parsed.domain ?? url.hostname;
33+
return `https://www.google.com/s2/favicons?domain=${encodeURIComponent(domain)}&sz=32`;
8334
} catch {
8435
return null;
8536
}

0 commit comments

Comments
 (0)