158 lines · 4.7 KB · TypeScript
RawDownload
import type { DesktopEnvironmentBootstrap } from "@t3tools/contracts";import type { KnownEnvironment } from "@t3tools/client-runtime"; export interface PrimaryEnvironmentTarget {  readonly source: KnownEnvironment["source"];  readonly target: KnownEnvironment["target"];} const LOOPBACK_HOSTNAMES = new Set(["127.0.0.1", "::1", "localhost"]); function getDesktopLocalEnvironmentBootstrap(): DesktopEnvironmentBootstrap | null {  return window.desktopBridge?.getLocalEnvironmentBootstrap() ?? null;} function normalizeBaseUrl(rawValue: string): string {  return new URL(rawValue, window.location.origin).toString();} function swapBaseUrlProtocol(  rawValue: string,  nextProtocol: "http:" | "https:" | "ws:" | "wss:",): string {  const url = new URL(normalizeBaseUrl(rawValue));  url.protocol = nextProtocol;  return url.toString();} function normalizeHostname(hostname: string): string {  return hostname    .trim()    .toLowerCase()    .replace(/^\[(.*)\]$/, "$1");} export function isLoopbackHostname(hostname: string): boolean {  return LOOPBACK_HOSTNAMES.has(normalizeHostname(hostname));} function resolveHttpRequestBaseUrl(httpBaseUrl: string): string {  const configuredDevServerUrl = import.meta.env.VITE_DEV_SERVER_URL?.trim();  if (!configuredDevServerUrl) {    return httpBaseUrl;  }   const currentUrl = new URL(window.location.href);  const targetUrl = new URL(httpBaseUrl);  const devServerUrl = new URL(configuredDevServerUrl, currentUrl.origin);   const isCurrentOriginDevServer =    (currentUrl.protocol === "http:" || currentUrl.protocol === "https:") &&    currentUrl.origin === devServerUrl.origin;   if (    !isCurrentOriginDevServer ||    currentUrl.origin === targetUrl.origin ||    !isLoopbackHostname(currentUrl.hostname) ||    !isLoopbackHostname(targetUrl.hostname)  ) {    return httpBaseUrl;  }   return currentUrl.origin;} function resolveConfiguredPrimaryTarget(): PrimaryEnvironmentTarget | null {  const configuredHttpBaseUrl = import.meta.env.VITE_HTTP_URL?.trim() || undefined;  const configuredWsBaseUrl = import.meta.env.VITE_WS_URL?.trim() || undefined;   if (!configuredHttpBaseUrl && !configuredWsBaseUrl) {    return null;  }   const resolvedHttpBaseUrl =    configuredHttpBaseUrl ??    (configuredWsBaseUrl?.startsWith("wss:")      ? swapBaseUrlProtocol(configuredWsBaseUrl, "https:")      : swapBaseUrlProtocol(configuredWsBaseUrl!, "http:"));  const resolvedWsBaseUrl =    configuredWsBaseUrl ??    (configuredHttpBaseUrl?.startsWith("https:")      ? swapBaseUrlProtocol(configuredHttpBaseUrl, "wss:")      : swapBaseUrlProtocol(configuredHttpBaseUrl!, "ws:"));   return {    source: "configured",    target: {      httpBaseUrl: normalizeBaseUrl(resolvedHttpBaseUrl),      wsBaseUrl: normalizeBaseUrl(resolvedWsBaseUrl),    },  };} function resolveWindowOriginPrimaryTarget(): PrimaryEnvironmentTarget {  const httpBaseUrl = normalizeBaseUrl(window.location.origin);  const url = new URL(httpBaseUrl);  if (url.protocol === "http:") {    url.protocol = "ws:";  } else if (url.protocol === "https:") {    url.protocol = "wss:";  } else {    throw new Error(`Unsupported HTTP base URL protocol: ${url.protocol}`);  }  return {    source: "window-origin",    target: {      httpBaseUrl,      wsBaseUrl: url.toString(),    },  };} function resolveDesktopPrimaryTarget(): PrimaryEnvironmentTarget | null {  const desktopBootstrap = getDesktopLocalEnvironmentBootstrap();  if (!desktopBootstrap) {    return null;  }  if (!desktopBootstrap.httpBaseUrl && !desktopBootstrap.wsBaseUrl) {    return null;  }  if (!desktopBootstrap.httpBaseUrl || !desktopBootstrap.wsBaseUrl) {    throw new Error(      "Desktop bootstrap must provide both httpBaseUrl and wsBaseUrl for the local environment.",    );  }   return {    source: "desktop-managed",    target: {      httpBaseUrl: normalizeBaseUrl(desktopBootstrap.httpBaseUrl),      wsBaseUrl: normalizeBaseUrl(desktopBootstrap.wsBaseUrl),    },  };} export function resolvePrimaryEnvironmentHttpUrl(  pathname: string,  searchParams?: Record<string, string>,): string {  const primaryTarget = readPrimaryEnvironmentTarget();  if (!primaryTarget) {    throw new Error("Unable to resolve the primary environment HTTP base URL.");  }   const url = new URL(resolveHttpRequestBaseUrl(primaryTarget.target.httpBaseUrl));  url.pathname = pathname;  if (searchParams) {    url.search = new URLSearchParams(searchParams).toString();  }  return url.toString();} export function readPrimaryEnvironmentTarget(): PrimaryEnvironmentTarget | null {  return (    resolveDesktopPrimaryTarget() ??    resolveConfiguredPrimaryTarget() ??    resolveWindowOriginPrimaryTarget()  );}