| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 | 'use strict'const UUID_REG = /^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iuconst URN_REG = /([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-.:;=@]|%[\da-f]{2})+)/iufunction isSecure (wsComponents) {  return typeof wsComponents.secure === 'boolean' ? wsComponents.secure : String(wsComponents.scheme).toLowerCase() === 'wss'}function httpParse (components) {  if (!components.host) {    components.error = components.error || 'HTTP URIs must have a host.'  }  return components}function httpSerialize (components) {  const secure = String(components.scheme).toLowerCase() === 'https'  // normalize the default port  if (components.port === (secure ? 443 : 80) || components.port === '') {    components.port = undefined  }  // normalize the empty path  if (!components.path) {    components.path = '/'  }  // NOTE: We do not parse query strings for HTTP URIs  // as WWW Form Url Encoded query strings are part of the HTML4+ spec,  // and not the HTTP spec.  return components}function wsParse (wsComponents) {// indicate if the secure flag is set  wsComponents.secure = isSecure(wsComponents)  // construct resouce name  wsComponents.resourceName = (wsComponents.path || '/') + (wsComponents.query ? '?' + wsComponents.query : '')  wsComponents.path = undefined  wsComponents.query = undefined  return wsComponents}function wsSerialize (wsComponents) {// normalize the default port  if (wsComponents.port === (isSecure(wsComponents) ? 443 : 80) || wsComponents.port === '') {    wsComponents.port = undefined  }  // ensure scheme matches secure flag  if (typeof wsComponents.secure === 'boolean') {    wsComponents.scheme = (wsComponents.secure ? 'wss' : 'ws')    wsComponents.secure = undefined  }  // reconstruct path from resource name  if (wsComponents.resourceName) {    const [path, query] = wsComponents.resourceName.split('?')    wsComponents.path = (path && path !== '/' ? path : undefined)    wsComponents.query = query    wsComponents.resourceName = undefined  }  // forbid fragment component  wsComponents.fragment = undefined  return wsComponents}function urnParse (urnComponents, options) {  if (!urnComponents.path) {    urnComponents.error = 'URN can not be parsed'    return urnComponents  }  const matches = urnComponents.path.match(URN_REG)  if (matches) {    const scheme = options.scheme || urnComponents.scheme || 'urn'    urnComponents.nid = matches[1].toLowerCase()    urnComponents.nss = matches[2]    const urnScheme = `${scheme}:${options.nid || urnComponents.nid}`    const schemeHandler = SCHEMES[urnScheme]    urnComponents.path = undefined    if (schemeHandler) {      urnComponents = schemeHandler.parse(urnComponents, options)    }  } else {    urnComponents.error = urnComponents.error || 'URN can not be parsed.'  }  return urnComponents}function urnSerialize (urnComponents, options) {  const scheme = options.scheme || urnComponents.scheme || 'urn'  const nid = urnComponents.nid.toLowerCase()  const urnScheme = `${scheme}:${options.nid || nid}`  const schemeHandler = SCHEMES[urnScheme]  if (schemeHandler) {    urnComponents = schemeHandler.serialize(urnComponents, options)  }  const uriComponents = urnComponents  const nss = urnComponents.nss  uriComponents.path = `${nid || options.nid}:${nss}`  options.skipEscape = true  return uriComponents}function urnuuidParse (urnComponents, options) {  const uuidComponents = urnComponents  uuidComponents.uuid = uuidComponents.nss  uuidComponents.nss = undefined  if (!options.tolerant && (!uuidComponents.uuid || !UUID_REG.test(uuidComponents.uuid))) {    uuidComponents.error = uuidComponents.error || 'UUID is not valid.'  }  return uuidComponents}function urnuuidSerialize (uuidComponents) {  const urnComponents = uuidComponents  // normalize UUID  urnComponents.nss = (uuidComponents.uuid || '').toLowerCase()  return urnComponents}const http = {  scheme: 'http',  domainHost: true,  parse: httpParse,  serialize: httpSerialize}const https = {  scheme: 'https',  domainHost: http.domainHost,  parse: httpParse,  serialize: httpSerialize}const ws = {  scheme: 'ws',  domainHost: true,  parse: wsParse,  serialize: wsSerialize}const wss = {  scheme: 'wss',  domainHost: ws.domainHost,  parse: ws.parse,  serialize: ws.serialize}const urn = {  scheme: 'urn',  parse: urnParse,  serialize: urnSerialize,  skipNormalize: true}const urnuuid = {  scheme: 'urn:uuid',  parse: urnuuidParse,  serialize: urnuuidSerialize,  skipNormalize: true}const SCHEMES = {  http,  https,  ws,  wss,  urn,  'urn:uuid': urnuuid}module.exports = SCHEMES
 |