1import { WORKSPACE_IMAGE_PREVIEW_EXTENSIONS } from "./filePreview.ts";
2
3export const PROJECT_FAVICON_FALLBACK_MARKER = "project-favicon-missing";
4
5export const PROJECT_FAVICON_EXTENSIONS = [...WORKSPACE_IMAGE_PREVIEW_EXTENSIONS, ".icns"] as const;
6
7export function isProjectFaviconPath(path: string): boolean {
8 const literalPath = path.toLowerCase();
9 return PROJECT_FAVICON_EXTENSIONS.some((extension) => literalPath.endsWith(extension));
10}
11
12export function getProjectFaviconResourceKey(
13 environmentId: string,
14 workspaceRoot: string,
15 faviconPath?: string | null,
16) {
17 return JSON.stringify([environmentId, workspaceRoot, faviconPath || null]);
18}
19
20export function getProjectFaviconCacheKey(
21 environmentId: string,
22 workspaceRoot: string,
23 url: string,
24) {
25 let revision = url;
26
27 try {
28 const pathname = new URL(url, "https://t3.invalid").pathname;
29 revision = pathname.slice(pathname.lastIndexOf("/") + 1);
30 } catch {
31 // Keep the full value as a safe fallback for malformed URLs.
32 }
33
34 return JSON.stringify([environmentId, workspaceRoot, revision]);
35}
36
37export function isProjectFaviconFallbackUrl(url: string | null | undefined): boolean {
38 if (!url) return false;
39
40 try {
41 const pathname = new URL(url, "https://t3.invalid").pathname;
42 return pathname.slice(pathname.lastIndexOf("/") + 1) === PROJECT_FAVICON_FALLBACK_MARKER;
43 } catch {
44 return false;
45 }
46}