import type { AdvertisedEndpoint, AdvertisedEndpointHostedHttpsCompatibility, AdvertisedEndpointProvider, AdvertisedEndpointReachability, AdvertisedEndpointSource, AdvertisedEndpointStatus, } from "@t3tools/contracts"; export interface CreateAdvertisedEndpointInput { readonly id: string; readonly label: string; readonly provider: AdvertisedEndpointProvider; readonly httpBaseUrl: string; readonly reachability: AdvertisedEndpointReachability; readonly hostedHttpsCompatibility?: AdvertisedEndpointHostedHttpsCompatibility; readonly desktopCompatibility?: "compatible" | "unknown"; readonly source: AdvertisedEndpointSource; readonly status?: AdvertisedEndpointStatus; readonly isDefault?: boolean; readonly description?: string; } export function normalizeHttpBaseUrl(rawValue: string): string { const url = new URL(rawValue); if (url.protocol === "ws:") { url.protocol = "http:"; } else if (url.protocol === "wss:") { url.protocol = "https:"; } if (url.protocol !== "http:" && url.protocol !== "https:") { throw new Error(`Endpoint must use HTTP or HTTPS. Received ${url.protocol}`); } url.pathname = "/"; url.search = ""; url.hash = ""; return url.toString(); } export function deriveWsBaseUrl(httpBaseUrl: string): string { const url = new URL(normalizeHttpBaseUrl(httpBaseUrl)); url.protocol = url.protocol === "https:" ? "wss:" : "ws:"; return url.toString(); } export function classifyHostedHttpsCompatibility( httpBaseUrl: string, fallback: AdvertisedEndpointHostedHttpsCompatibility = "unknown", ): AdvertisedEndpointHostedHttpsCompatibility { const url = new URL(normalizeHttpBaseUrl(httpBaseUrl)); if (url.protocol === "http:") { return "mixed-content-blocked"; } return fallback === "mixed-content-blocked" ? "unknown" : fallback; } export function createAdvertisedEndpoint(input: CreateAdvertisedEndpointInput): AdvertisedEndpoint { const httpBaseUrl = normalizeHttpBaseUrl(input.httpBaseUrl); return { id: input.id, label: input.label, provider: input.provider, httpBaseUrl, wsBaseUrl: deriveWsBaseUrl(httpBaseUrl), reachability: input.reachability, compatibility: { hostedHttpsApp: input.hostedHttpsCompatibility ?? classifyHostedHttpsCompatibility(httpBaseUrl), desktopApp: input.desktopCompatibility ?? "compatible", }, source: input.source, status: input.status ?? "available", ...(input.isDefault === undefined ? {} : { isDefault: input.isDefault }), ...(input.description === undefined ? {} : { description: input.description }), }; }