import { registryGatewayWsUrl } from './plugin-profile-routes' export interface RegistryGatewayWsConnection { authMode: string baseUrl: string wsUrl: string headers?: Record profile?: null | string sharedRemote?: boolean } interface RegistryGatewayWsUrlDependencies { ensureBackend: (connectionId: unknown, profile: unknown) => Promise mintTicket: (baseUrl: string, headers?: Record) => Promise buildTicketUrl: (baseUrl: string, ticket: string) => string rememberHeaders: (wsUrl: string, headers?: Record) => void } interface RemoteRequestDetails { url: string requestHeaders?: Record } type RemoteRequestCallback = (result: { requestHeaders?: Record }) => void export function createRemoteWsHeaderStore(limit = 100) { const headersByUrl = new Map>() const remember = (wsUrl: string, headers: Record = {}) => { if (!wsUrl || Object.keys(headers).length === 0) { return } headersByUrl.set(String(wsUrl), headers) while (headersByUrl.size > limit) { const oldest = headersByUrl.keys().next().value if (!oldest) { break } headersByUrl.delete(oldest) } } const headersFor = (requestUrl: string): Record => { const key = String(requestUrl) const headers = headersByUrl.get(key) if (!headers) { return {} } headersByUrl.delete(key) headersByUrl.set(key, headers) return headers } return { headersFor, remember } } export function applyRemoteRequestHeaders( details: RemoteRequestDetails, callback: RemoteRequestCallback, headersForRequest: (requestUrl: string) => Record ) { const headers = headersForRequest(details.url) if (Object.keys(headers).length === 0) { callback({}) return } callback({ requestHeaders: { ...details.requestHeaders, ...headers } }) } export function createRegistryGatewayWsUrlHandler(dependencies: RegistryGatewayWsUrlDependencies) { return async (payload: unknown): Promise => { const { connectionId, profile } = payload && typeof payload === 'object' ? (payload as any) : ({} as any) const connection = await dependencies.ensureBackend(connectionId, profile) let wsUrl = connection.wsUrl if (connection.authMode === 'oauth') { const ticket = await dependencies.mintTicket(connection.baseUrl, connection.headers) wsUrl = dependencies.buildTicketUrl(connection.baseUrl, ticket) } const finalWsUrl = registryGatewayWsUrl(connection, wsUrl) dependencies.rememberHeaders(finalWsUrl, connection.headers) return finalWsUrl } }