Buckets:
| const { isUUID } = require('./utils') | |
| const URN_REG = /([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-.:;=@]|%[\da-f]{2})+)/iu | |
| const supportedSchemeNames = /** @type {const} */ (['http', 'https', 'ws', | |
| 'wss', 'urn', 'urn:uuid']) | |
| /** @typedef {supportedSchemeNames[number]} SchemeName */ | |
| /** | |
| * @param {string} name | |
| * @returns {name is SchemeName} | |
| */ | |
| function isValidSchemeName (name) { | |
| return supportedSchemeNames.indexOf(/** @type {*} */ (name)) !== -1 | |
| } | |
| /** | |
| * @callback SchemeFn | |
| * @param {import('../types/index').URIComponent} component | |
| * @param {import('../types/index').Options} options | |
| * @returns {import('../types/index').URIComponent} | |
| */ | |
| /** | |
| * @typedef {Object} SchemeHandler | |
| * @property {SchemeName} scheme - The scheme name. | |
| * @property {boolean} [domainHost] - Indicates if the scheme supports domain hosts. | |
| * @property {SchemeFn} parse - Function to parse the URI component for this scheme. | |
| * @property {SchemeFn} serialize - Function to serialize the URI component for this scheme. | |
| * @property {boolean} [skipNormalize] - Indicates if normalization should be skipped for this scheme. | |
| * @property {boolean} [absolutePath] - Indicates if the scheme uses absolute paths. | |
| * @property {boolean} [unicodeSupport] - Indicates if the scheme supports Unicode. | |
| */ | |
| /** | |
| * @param {import('../types/index').URIComponent} wsComponent | |
| * @returns {boolean} | |
| */ | |
| function wsIsSecure (wsComponent) { | |
| if (wsComponent.secure === true) { | |
| return true | |
| } else if (wsComponent.secure === false) { | |
| return false | |
| } else if (wsComponent.scheme) { | |
| return ( | |
| wsComponent.scheme.length === 3 && | |
| (wsComponent.scheme[0] === 'w' || wsComponent.scheme[0] === 'W') && | |
| (wsComponent.scheme[1] === 's' || wsComponent.scheme[1] === 'S') && | |
| (wsComponent.scheme[2] === 's' || wsComponent.scheme[2] === 'S') | |
| ) | |
| } else { | |
| return false | |
| } | |
| } | |
| /** @type {SchemeFn} */ | |
| function httpParse (component) { | |
| if (!component.host) { | |
| component.error = component.error || 'HTTP URIs must have a host.' | |
| } | |
| return component | |
| } | |
| /** @type {SchemeFn} */ | |
| function httpSerialize (component) { | |
| const secure = String(component.scheme).toLowerCase() === 'https' | |
| // normalize the default port | |
| if (component.port === (secure ? 443 : 80) || component.port === '') { | |
| component.port = undefined | |
| } | |
| // normalize the empty path | |
| if (!component.path) { | |
| component.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 component | |
| } | |
| /** @type {SchemeFn} */ | |
| function wsParse (wsComponent) { | |
| // indicate if the secure flag is set | |
| wsComponent.secure = wsIsSecure(wsComponent) | |
| // construct resouce name | |
| wsComponent.resourceName = (wsComponent.path || '/') + (wsComponent.query ? '?' + wsComponent.query : '') | |
| wsComponent.path = undefined | |
| wsComponent.query = undefined | |
| return wsComponent | |
| } | |
| /** @type {SchemeFn} */ | |
| function wsSerialize (wsComponent) { | |
| // normalize the default port | |
| if (wsComponent.port === (wsIsSecure(wsComponent) ? 443 : 80) || wsComponent.port === '') { | |
| wsComponent.port = undefined | |
| } | |
| // ensure scheme matches secure flag | |
| if (typeof wsComponent.secure === 'boolean') { | |
| wsComponent.scheme = (wsComponent.secure ? 'wss' : 'ws') | |
| wsComponent.secure = undefined | |
| } | |
| // reconstruct path from resource name | |
| if (wsComponent.resourceName) { | |
| const [path, query] = wsComponent.resourceName.split('?') | |
| wsComponent.path = (path && path !== '/' ? path : undefined) | |
| wsComponent.query = query | |
| wsComponent.resourceName = undefined | |
| } | |
| // forbid fragment component | |
| wsComponent.fragment = undefined | |
| return wsComponent | |
| } | |
| /** @type {SchemeFn} */ | |
| function urnParse (urnComponent, options) { | |
| if (!urnComponent.path) { | |
| urnComponent.error = 'URN can not be parsed' | |
| return urnComponent | |
| } | |
| const matches = urnComponent.path.match(URN_REG) | |
| if (matches) { | |
| const scheme = options.scheme || urnComponent.scheme || 'urn' | |
| urnComponent.nid = matches[1].toLowerCase() | |
| urnComponent.nss = matches[2] | |
| const urnScheme = `${scheme}:${options.nid || urnComponent.nid}` | |
| const schemeHandler = getSchemeHandler(urnScheme) | |
| urnComponent.path = undefined | |
| if (schemeHandler) { | |
| urnComponent = schemeHandler.parse(urnComponent, options) | |
| } | |
| } else { | |
| urnComponent.error = urnComponent.error || 'URN can not be parsed.' | |
| } | |
| return urnComponent | |
| } | |
| /** @type {SchemeFn} */ | |
| function urnSerialize (urnComponent, options) { | |
| if (urnComponent.nid === undefined) { | |
| throw new Error('URN without nid cannot be serialized') | |
| } | |
| const scheme = options.scheme || urnComponent.scheme || 'urn' | |
| const nid = urnComponent.nid.toLowerCase() | |
| const urnScheme = `${scheme}:${options.nid || nid}` | |
| const schemeHandler = getSchemeHandler(urnScheme) | |
| if (schemeHandler) { | |
| urnComponent = schemeHandler.serialize(urnComponent, options) | |
| } | |
| const uriComponent = urnComponent | |
| const nss = urnComponent.nss | |
| uriComponent.path = `${nid || options.nid}:${nss}` | |
| options.skipEscape = true | |
| return uriComponent | |
| } | |
| /** @type {SchemeFn} */ | |
| function urnuuidParse (urnComponent, options) { | |
| const uuidComponent = urnComponent | |
| uuidComponent.uuid = uuidComponent.nss | |
| uuidComponent.nss = undefined | |
| if (!options.tolerant && (!uuidComponent.uuid || !isUUID(uuidComponent.uuid))) { | |
| uuidComponent.error = uuidComponent.error || 'UUID is not valid.' | |
| } | |
| return uuidComponent | |
| } | |
| /** @type {SchemeFn} */ | |
| function urnuuidSerialize (uuidComponent) { | |
| const urnComponent = uuidComponent | |
| // normalize UUID | |
| urnComponent.nss = (uuidComponent.uuid || '').toLowerCase() | |
| return urnComponent | |
| } | |
| const http = /** @type {SchemeHandler} */ ({ | |
| scheme: 'http', | |
| domainHost: true, | |
| parse: httpParse, | |
| serialize: httpSerialize | |
| }) | |
| const https = /** @type {SchemeHandler} */ ({ | |
| scheme: 'https', | |
| domainHost: http.domainHost, | |
| parse: httpParse, | |
| serialize: httpSerialize | |
| }) | |
| const ws = /** @type {SchemeHandler} */ ({ | |
| scheme: 'ws', | |
| domainHost: true, | |
| parse: wsParse, | |
| serialize: wsSerialize | |
| }) | |
| const wss = /** @type {SchemeHandler} */ ({ | |
| scheme: 'wss', | |
| domainHost: ws.domainHost, | |
| parse: ws.parse, | |
| serialize: ws.serialize | |
| }) | |
| const urn = /** @type {SchemeHandler} */ ({ | |
| scheme: 'urn', | |
| parse: urnParse, | |
| serialize: urnSerialize, | |
| skipNormalize: true | |
| }) | |
| const urnuuid = /** @type {SchemeHandler} */ ({ | |
| scheme: 'urn:uuid', | |
| parse: urnuuidParse, | |
| serialize: urnuuidSerialize, | |
| skipNormalize: true | |
| }) | |
| const SCHEMES = /** @type {Record<SchemeName, SchemeHandler>} */ ({ | |
| http, | |
| https, | |
| ws, | |
| wss, | |
| urn, | |
| 'urn:uuid': urnuuid | |
| }) | |
| Object.setPrototypeOf(SCHEMES, null) | |
| /** | |
| * @param {string|undefined} scheme | |
| * @returns {SchemeHandler|undefined} | |
| */ | |
| function getSchemeHandler (scheme) { | |
| return ( | |
| scheme && ( | |
| SCHEMES[/** @type {SchemeName} */ (scheme)] || | |
| SCHEMES[/** @type {SchemeName} */(scheme.toLowerCase())]) | |
| ) || | |
| undefined | |
| } | |
| module.exports = { | |
| wsIsSecure, | |
| SCHEMES, | |
| isValidSchemeName, | |
| getSchemeHandler, | |
| } | |
Xet Storage Details
- Size:
- 7.12 kB
- Xet hash:
- cd75e34583d0b980023168d89e57c2558abc28270c0bb9fbea30fdb6dee3cd50
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.