export function ensureProtocol (value) { if (!value) return value value = value.trim() if (!/^([a-z0-9]+:\/\/|mailto:)/.test(value)) { value = 'http://' + value } return value } export function isExternal (url) { return !url.startsWith(process.env.PUBLIC_URL + '/') && !url.startsWith('/') } export function removeTracking (value) { if (!value) return value const exprs = [ // twitter URLs /^(?https?:\/\/(?:twitter|x)\.com\/(?:#!\/)?(?\w+)\/status(?:es)?\/(?\d+))/ ] for (const expr of exprs) { value = expr.exec(value)?.groups.url ?? value } return value } export function stripTrailingSlash (uri) { return uri.endsWith('/') ? uri.slice(0, -1) : uri } export function parseNwcUrl (walletConnectUrl) { if (!walletConnectUrl) return {} walletConnectUrl = walletConnectUrl .replace('nostrwalletconnect://', 'http://') .replace('nostr+walletconnect://', 'http://') // makes it possible to parse with URL in the different environments (browser/node/...) // XXX There is a bug in parsing since we use the URL constructor for parsing: // A wallet pubkey matching /^[0-9a-fA-F]{64}$/ might not be a valid hostname. // Example: 11111111111 (10 1's) is a valid hostname (gets parsed as IPv4) but 111111111111 (11 1's) is not. // See https://stackoverflow.com/questions/56804936/how-does-only-numbers-in-url-resolve-to-a-domain // However, this seems to only get triggered if a wallet pubkey only contains digits so this is pretty improbable. const url = new URL(walletConnectUrl) const params = {} params.walletPubkey = url.host const secret = url.searchParams.get('secret') const relayUrl = url.searchParams.get('relay') if (secret) { params.secret = secret } if (relayUrl) { params.relayUrl = relayUrl } return params } // eslint-disable-next-line export const URL_REGEXP = /^((https?|ftp):\/\/)?(www.)?(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i // eslint-disable-next-line export const WS_REGEXP = /^(wss?:\/\/)([0-9]{1,3}(?:\.[0-9]{1,3}){3}|(?=[^\/]{1,254}(?![^\/]))(?:(?=[a-zA-Z0-9-]{1,63}\.)(?:xn--+)?[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*\.)+[a-zA-Z]{2,63})(:([0-9]{1,5}))?(\/[^\s`@#$^&=.?"{}\\]+\/?)*([^\s`@#$^&=?"{}\/\\]+)?(\?[^\s`#$^"{}\\]+)*$/ export const IMGPROXY_URL_REGEXP = new RegExp(`^${process.env.NEXT_PUBLIC_IMGPROXY_URL}.*$`) // this regex is not a bullet proof way of checking if a url points to an image. to be sure, fetch the url and check the mimetype export const IMG_URL_REGEXP = /^(https?:\/\/.*\.(?:png|jpg|jpeg|gif))$/