mission-control/src/lib/gateway-url.ts

61 lines
1.6 KiB
TypeScript

function isLocalHost(host: string): boolean {
const normalized = host.toLowerCase()
return (
normalized === 'localhost' ||
normalized === '127.0.0.1' ||
normalized === '::1' ||
normalized.endsWith('.local')
)
}
function normalizeProtocol(protocol: string): 'ws:' | 'wss:' {
if (protocol === 'https:' || protocol === 'wss:') return 'wss:'
return 'ws:'
}
export function buildGatewayWebSocketUrl(input: {
host: string
port: number
browserProtocol?: string
}): string {
const rawHost = String(input.host || '').trim()
const port = Number(input.port)
const browserProtocol = input.browserProtocol === 'https:' ? 'https:' : 'http:'
if (!rawHost) {
return `${browserProtocol === 'https:' ? 'wss' : 'ws'}://127.0.0.1:${port || 18789}`
}
const prefixed =
rawHost.startsWith('ws://') ||
rawHost.startsWith('wss://') ||
rawHost.startsWith('http://') ||
rawHost.startsWith('https://')
? rawHost
: null
if (prefixed) {
try {
const parsed = new URL(prefixed)
parsed.protocol = normalizeProtocol(parsed.protocol)
// Users often paste dashboard/session URLs; websocket connect should target gateway root.
parsed.pathname = '/'
parsed.search = ''
parsed.hash = ''
return parsed.toString().replace(/\/$/, '')
} catch {
return prefixed
}
}
const wsProtocol = browserProtocol === 'https:' ? 'wss' : 'ws'
const shouldOmitPort =
wsProtocol === 'wss' &&
!isLocalHost(rawHost) &&
port === 18789
return shouldOmitPort
? `${wsProtocol}://${rawHost}`
: `${wsProtocol}://${rawHost}:${port || 18789}`
}