mirror of
https://github.com/nodejs/node.git
synced 2025-05-17 20:06:54 +00:00

BUGFIXES * [`27cccfbda`](27cccfbdac
) [#223](https://github.com/npm/cli/pull/223) vulns → vulnerabilities in npm audit output ([@sapegin](https://github.com/sapegin)) * [`d5e865eb7`](d5e865eb79
) [#222](https://github.com/npm/cli/pull/222) [#226](https://github.com/npm/cli/pull/226) install, doctor: don't crash if registry unset ([@dmitrydvorkin](https://github.com/dmitrydvorkin), [@isaacs](https://github.com/isaacs)) * [`5b3890226`](5b38902265
) [#227](https://github.com/npm/cli/pull/227) [npm.community#9167](https://npm.community/t/npm-err-cb-never-called-permission-denied/9167/5) Handle unhandledRejections, tell user what to do when encountering an `EACCES` error in the cache. ([@isaacs](https://github.com/isaacs)) DEPENDENCIES * [`77516df6e`](77516df6ea
) `licensee@7.0.3` ([@isaacs](https://github.com/isaacs)) * [`ceb993590`](ceb993590e
) `query-string@6.8.2` ([@isaacs](https://github.com/isaacs)) * [`4050b9189`](4050b91898
) `hosted-git-info@2.8.2` * [#46](https://github.com/npm/hosted-git-info/issues/46) [#43](https://github.com/npm/hosted-git-info/issues/43) [#47](https://github.com/npm/hosted-git-info/pull/47) [#44](https://github.com/npm/hosted-git-info/pull/44) Add support for GitLab subgroups ([@mterrel](https://github.com/mterrel), [@isaacs](https://github.com/isaacs), [@ybiquitous](https://github.com/ybiquitous)) * [`3b1d629`](https://github.com/npm/hosted-git-info/commit/3b1d629) [#48](https://github.com/npm/hosted-git-info/issues/48) fix http protocol using sshurl by default ([@fengmk2](https://github.com/fengmk2)) * [`5d4a8d7`](https://github.com/npm/hosted-git-info/commit/5d4a8d7) ignore noCommittish on tarball url generation ([@isaacs](https://github.com/isaacs)) * [`1692435`](https://github.com/npm/hosted-git-info/commit/1692435) use gist tarball url that works for anonymous gists ([@isaacs](https://github.com/isaacs)) * [`d5cf830`](d5cf8309be
) Do not allow invalid gist urls ([@isaacs](https://github.com/isaacs)) * [`e518222`](e518222435
) Use LRU cache to prevent unbounded memory consumption ([@iarna](https://github.com/iarna)) PR-URL: https://github.com/nodejs/node/pull/29023 Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
125 lines
4.0 KiB
JavaScript
125 lines
4.0 KiB
JavaScript
'use strict'
|
|
var url = require('url')
|
|
var gitHosts = require('./git-host-info.js')
|
|
var GitHost = module.exports = require('./git-host.js')
|
|
var LRU = require('lru-cache')
|
|
var cache = new LRU({max: 1000})
|
|
|
|
var protocolToRepresentationMap = {
|
|
'git+ssh:': 'sshurl',
|
|
'git+https:': 'https',
|
|
'ssh:': 'sshurl',
|
|
'git:': 'git'
|
|
}
|
|
|
|
function protocolToRepresentation (protocol) {
|
|
return protocolToRepresentationMap[protocol] || protocol.slice(0, -1)
|
|
}
|
|
|
|
var authProtocols = {
|
|
'git:': true,
|
|
'https:': true,
|
|
'git+https:': true,
|
|
'http:': true,
|
|
'git+http:': true
|
|
}
|
|
|
|
module.exports.fromUrl = function (giturl, opts) {
|
|
if (typeof giturl !== 'string') return
|
|
var key = giturl + JSON.stringify(opts || {})
|
|
|
|
if (!cache.has(key)) {
|
|
cache.set(key, fromUrl(giturl, opts))
|
|
}
|
|
|
|
return cache.get(key)
|
|
}
|
|
|
|
function fromUrl (giturl, opts) {
|
|
if (giturl == null || giturl === '') return
|
|
var url = fixupUnqualifiedGist(
|
|
isGitHubShorthand(giturl) ? 'github:' + giturl : giturl
|
|
)
|
|
var parsed = parseGitUrl(url)
|
|
var shortcutMatch = url.match(new RegExp('^([^:]+):(?:(?:[^@:]+(?:[^@]+)?@)?([^/]*))[/](.+?)(?:[.]git)?($|#)'))
|
|
var matches = Object.keys(gitHosts).map(function (gitHostName) {
|
|
try {
|
|
var gitHostInfo = gitHosts[gitHostName]
|
|
var auth = null
|
|
if (parsed.auth && authProtocols[parsed.protocol]) {
|
|
auth = decodeURIComponent(parsed.auth)
|
|
}
|
|
var committish = parsed.hash ? decodeURIComponent(parsed.hash.substr(1)) : null
|
|
var user = null
|
|
var project = null
|
|
var defaultRepresentation = null
|
|
if (shortcutMatch && shortcutMatch[1] === gitHostName) {
|
|
user = shortcutMatch[2] && decodeURIComponent(shortcutMatch[2])
|
|
project = decodeURIComponent(shortcutMatch[3])
|
|
defaultRepresentation = 'shortcut'
|
|
} else {
|
|
if (parsed.host && parsed.host !== gitHostInfo.domain && parsed.host.replace(/^www[.]/, '') !== gitHostInfo.domain) return
|
|
if (!gitHostInfo.protocols_re.test(parsed.protocol)) return
|
|
if (!parsed.path) return
|
|
var pathmatch = gitHostInfo.pathmatch
|
|
var matched = parsed.path.match(pathmatch)
|
|
if (!matched) return
|
|
if (matched[1] !== null && matched[1] !== undefined) {
|
|
user = decodeURIComponent(matched[1].replace(/^:/, ''))
|
|
}
|
|
project = decodeURIComponent(matched[2])
|
|
defaultRepresentation = protocolToRepresentation(parsed.protocol)
|
|
}
|
|
return new GitHost(gitHostName, user, auth, project, committish, defaultRepresentation, opts)
|
|
} catch (ex) {
|
|
/* istanbul ignore else */
|
|
if (ex instanceof URIError) {
|
|
} else throw ex
|
|
}
|
|
}).filter(function (gitHostInfo) { return gitHostInfo })
|
|
if (matches.length !== 1) return
|
|
return matches[0]
|
|
}
|
|
|
|
function isGitHubShorthand (arg) {
|
|
// Note: This does not fully test the git ref format.
|
|
// See https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html
|
|
//
|
|
// The only way to do this properly would be to shell out to
|
|
// git-check-ref-format, and as this is a fast sync function,
|
|
// we don't want to do that. Just let git fail if it turns
|
|
// out that the commit-ish is invalid.
|
|
// GH usernames cannot start with . or -
|
|
return /^[^:@%/\s.-][^:@%/\s]*[/][^:@\s/%]+(?:#.*)?$/.test(arg)
|
|
}
|
|
|
|
function fixupUnqualifiedGist (giturl) {
|
|
// necessary for round-tripping gists
|
|
var parsed = url.parse(giturl)
|
|
if (parsed.protocol === 'gist:' && parsed.host && !parsed.path) {
|
|
return parsed.protocol + '/' + parsed.host
|
|
} else {
|
|
return giturl
|
|
}
|
|
}
|
|
|
|
function parseGitUrl (giturl) {
|
|
var matched = giturl.match(/^([^@]+)@([^:/]+):[/]?((?:[^/]+[/])?[^/]+?)(?:[.]git)?(#.*)?$/)
|
|
if (!matched) return url.parse(giturl)
|
|
return {
|
|
protocol: 'git+ssh:',
|
|
slashes: true,
|
|
auth: matched[1],
|
|
host: matched[2],
|
|
port: null,
|
|
hostname: matched[2],
|
|
hash: matched[4],
|
|
search: null,
|
|
query: null,
|
|
pathname: '/' + matched[3],
|
|
path: '/' + matched[3],
|
|
href: 'git+ssh://' + matched[1] + '@' + matched[2] +
|
|
'/' + matched[3] + (matched[4] || '')
|
|
}
|
|
}
|