Files
welshman/packages/util/src/Relay.ts
T

88 lines
2.1 KiB
TypeScript

import {last, normalizeUrl, stripProtocol} from "@welshman/lib"
// Constants and types
export enum RelayMode {
Read = "read",
Write = "write",
Inbox = "inbox",
}
export type RelayProfile = {
url: string
icon?: string
banner?: string
name?: string
self?: string
pubkey?: string
contact?: string
software?: string
version?: string
negentropy?: number
description?: string
supported_nips?: number[]
privacy_policy?: string
terms_of_service?: string
limitation?: {
min_pow_difficulty?: number
payment_required?: boolean
auth_required?: boolean
}
}
// Utils related to bare urls
export const isRelayUrl = (url: string) => {
if (!url.includes("://")) {
url = "wss://" + url
}
// Skip non-ws urls
if (!url.match(/^wss?:\/\//)) return false
// Skip urls with a slash before the dot
if (url.match(/\\.*\./)) return false
// Skip non-localhost urls without a dot
if (!url.match(/\./) && !url.includes("localhost")) return false
try {
new URL(url)
} catch (e) {
return false
}
return true
}
export const isOnionUrl = (url: string) => Boolean(stripProtocol(url).match(/^[a-z2-7]{56}.onion/))
export const isLocalUrl = (url: string) =>
Boolean(url.match(/\.local(:[\d]+)?\/?$/) || stripProtocol(url).match(/^localhost:/))
export const isIPAddress = (url: string) => Boolean(url.match(/\d+\.\d+\.\d+\.\d+/))
export const isShareableRelayUrl = (url: string) => Boolean(isRelayUrl(url) && !isLocalUrl(url))
export const normalizeRelayUrl = (url: string) => {
const prefix = url.match(/^wss?:\/\//)?.[0] || (isOnionUrl(url) ? "ws://" : "wss://")
// Use our library to normalize
url = normalizeUrl(url, {stripHash: true, stripAuthentication: false})
// Strip the protocol, lowercase
url = stripProtocol(url).toLowerCase()
// Urls without pathnames are supposed to have a trailing slash
if (!url.includes("/")) {
url += "/"
}
return prefix + url
}
export const displayRelayUrl = (url: string) => last(url.split("://")).replace(/\/$/, "")
export const displayRelayProfile = (profile?: RelayProfile, fallback = "") =>
profile?.name || fallback