Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

index.js 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. 'use strict'
  2. var url = require('url')
  3. var gitHosts = require('./git-host-info.js')
  4. var GitHost = module.exports = require('./git-host.js')
  5. var LRU = require('lru-cache')
  6. var cache = new LRU({max: 1000})
  7. var protocolToRepresentationMap = {
  8. 'git+ssh:': 'sshurl',
  9. 'git+https:': 'https',
  10. 'ssh:': 'sshurl',
  11. 'git:': 'git'
  12. }
  13. function protocolToRepresentation (protocol) {
  14. return protocolToRepresentationMap[protocol] || protocol.slice(0, -1)
  15. }
  16. var authProtocols = {
  17. 'git:': true,
  18. 'https:': true,
  19. 'git+https:': true,
  20. 'http:': true,
  21. 'git+http:': true
  22. }
  23. module.exports.fromUrl = function (giturl, opts) {
  24. if (typeof giturl !== 'string') return
  25. var key = giturl + JSON.stringify(opts || {})
  26. if (!cache.has(key)) {
  27. cache.set(key, fromUrl(giturl, opts))
  28. }
  29. return cache.get(key)
  30. }
  31. function fromUrl (giturl, opts) {
  32. if (giturl == null || giturl === '') return
  33. var url = fixupUnqualifiedGist(
  34. isGitHubShorthand(giturl) ? 'github:' + giturl : giturl
  35. )
  36. var parsed = parseGitUrl(url)
  37. var shortcutMatch = url.match(new RegExp('^([^:]+):(?:(?:[^@:]+(?:[^@]+)?@)?([^/]*))[/](.+?)(?:[.]git)?($|#)'))
  38. var matches = Object.keys(gitHosts).map(function (gitHostName) {
  39. try {
  40. var gitHostInfo = gitHosts[gitHostName]
  41. var auth = null
  42. if (parsed.auth && authProtocols[parsed.protocol]) {
  43. auth = parsed.auth
  44. }
  45. var committish = parsed.hash ? decodeURIComponent(parsed.hash.substr(1)) : null
  46. var user = null
  47. var project = null
  48. var defaultRepresentation = null
  49. if (shortcutMatch && shortcutMatch[1] === gitHostName) {
  50. user = shortcutMatch[2] && decodeURIComponent(shortcutMatch[2])
  51. project = decodeURIComponent(shortcutMatch[3])
  52. defaultRepresentation = 'shortcut'
  53. } else {
  54. if (parsed.host && parsed.host !== gitHostInfo.domain && parsed.host.replace(/^www[.]/, '') !== gitHostInfo.domain) return
  55. if (!gitHostInfo.protocols_re.test(parsed.protocol)) return
  56. if (!parsed.path) return
  57. var pathmatch = gitHostInfo.pathmatch
  58. var matched = parsed.path.match(pathmatch)
  59. if (!matched) return
  60. /* istanbul ignore else */
  61. if (matched[1] !== null && matched[1] !== undefined) {
  62. user = decodeURIComponent(matched[1].replace(/^:/, ''))
  63. }
  64. project = decodeURIComponent(matched[2])
  65. defaultRepresentation = protocolToRepresentation(parsed.protocol)
  66. }
  67. return new GitHost(gitHostName, user, auth, project, committish, defaultRepresentation, opts)
  68. } catch (ex) {
  69. /* istanbul ignore else */
  70. if (ex instanceof URIError) {
  71. } else throw ex
  72. }
  73. }).filter(function (gitHostInfo) { return gitHostInfo })
  74. if (matches.length !== 1) return
  75. return matches[0]
  76. }
  77. function isGitHubShorthand (arg) {
  78. // Note: This does not fully test the git ref format.
  79. // See https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html
  80. //
  81. // The only way to do this properly would be to shell out to
  82. // git-check-ref-format, and as this is a fast sync function,
  83. // we don't want to do that. Just let git fail if it turns
  84. // out that the commit-ish is invalid.
  85. // GH usernames cannot start with . or -
  86. return /^[^:@%/\s.-][^:@%/\s]*[/][^:@\s/%]+(?:#.*)?$/.test(arg)
  87. }
  88. function fixupUnqualifiedGist (giturl) {
  89. // necessary for round-tripping gists
  90. var parsed = url.parse(giturl)
  91. if (parsed.protocol === 'gist:' && parsed.host && !parsed.path) {
  92. return parsed.protocol + '/' + parsed.host
  93. } else {
  94. return giturl
  95. }
  96. }
  97. function parseGitUrl (giturl) {
  98. var matched = giturl.match(/^([^@]+)@([^:/]+):[/]?((?:[^/]+[/])?[^/]+?)(?:[.]git)?(#.*)?$/)
  99. if (!matched) {
  100. var legacy = url.parse(giturl)
  101. if (legacy.auth) {
  102. // git urls can be in the form of scp-style/ssh-connect strings, like
  103. // git+ssh://user@host.com:some/path, which the legacy url parser
  104. // supports, but WhatWG url.URL class does not. However, the legacy
  105. // parser de-urlencodes the username and password, so something like
  106. // https://user%3An%40me:p%40ss%3Aword@x.com/ becomes
  107. // https://user:n@me:p@ss:word@x.com/ which is all kinds of wrong.
  108. // Pull off just the auth and host, so we dont' get the confusing
  109. // scp-style URL, then pass that to the WhatWG parser to get the
  110. // auth properly escaped.
  111. const authmatch = giturl.match(/[^@]+@[^:/]+/)
  112. /* istanbul ignore else - this should be impossible */
  113. if (authmatch) {
  114. var whatwg = new url.URL(authmatch[0])
  115. legacy.auth = whatwg.username || ''
  116. if (whatwg.password) legacy.auth += ':' + whatwg.password
  117. }
  118. }
  119. return legacy
  120. }
  121. return {
  122. protocol: 'git+ssh:',
  123. slashes: true,
  124. auth: matched[1],
  125. host: matched[2],
  126. port: null,
  127. hostname: matched[2],
  128. hash: matched[4],
  129. search: null,
  130. query: null,
  131. pathname: '/' + matched[3],
  132. path: '/' + matched[3],
  133. href: 'git+ssh://' + matched[1] + '@' + matched[2] +
  134. '/' + matched[3] + (matched[4] || '')
  135. }
  136. }