UNPKG

github-url-to-object

Version:

Extract user, repo, and other interesting properties from GitHub URLs

98 lines (78 loc) 3.23 kB
'use strict' var isUrl = require('is-url') var laxUrlRegex = /(?:(?:[^:]+:)?[/][/])?(?:.+@)?([^/]+)([/][^?#]+)/ module.exports = function (repoUrl, opts) { var obj = {} opts = opts || {} if (!repoUrl) return null // Allow an object with nested `url` string // (common practice in package.json files) if (repoUrl.url) repoUrl = repoUrl.url if (typeof repoUrl !== 'string') return null var shorthand = repoUrl.match(/^([\w-_]+)\/([\w-_\.]+)(?:#([\w-_\.]+))?$/) var mediumhand = repoUrl.match(/^github:([\w-_]+)\/([\w-_\.]+)(?:#([\w-_\.]+))?$/) var antiquated = repoUrl.match(/^git@[\w-_\.]+:([\w-_]+)\/([\w-_\.]+)$/) if (shorthand) { obj.user = shorthand[1] obj.repo = shorthand[2] obj.branch = shorthand[3] || 'master' obj.host = 'github.com' } else if (mediumhand) { obj.user = mediumhand[1] obj.repo = mediumhand[2] obj.branch = mediumhand[3] || 'master' obj.host = 'github.com' } else if (antiquated) { obj.user = antiquated[1] obj.repo = antiquated[2].replace(/\.git$/i, '') obj.branch = 'master' obj.host = 'github.com' } else { // Turn git+http URLs into http URLs repoUrl = repoUrl.replace(/^git\+/, '') if (!isUrl(repoUrl)) return null const [, hostname, pathname] = repoUrl.match(laxUrlRegex) || [] if (!hostname) return null if (hostname !== 'github.com' && hostname !== 'www.github.com' && !opts.enterprise) return null var parts = pathname.match(/^\/([\w-_]+)\/([\w-_\.]+)(\/tree\/[%\w-_\.\/]+)?(\/blob\/[%\w-_\.\/]+)?/) // ([\w-_\.]+) if (!parts) return null obj.user = parts[1] obj.repo = parts[2].replace(/\.git$/i, '') obj.host = hostname || 'github.com' if (parts[3] && /^\/tree\/master\//.test(parts[3])) { obj.branch = 'master' obj.path = parts[3].replace(/\/$/, '') } else if (parts[3]) { const branchMatch = parts[3].replace(/^\/tree\//, '').match(/[%\w-_.]*\/?[%\w-_]+/) obj.branch = branchMatch && branchMatch[0] } else if (parts[4]) { const branchMatch = parts[4].replace(/^\/blob\//, '').match(/[%\w-_.]*\/?[%\w-_]+/) obj.branch = branchMatch && branchMatch[0] } else { obj.branch = 'master' } } if (obj.host === 'github.com') { obj.apiHost = 'api.github.com' } else { obj.apiHost = `${obj.host}/api/v3` } obj.tarball_url = `https://${obj.apiHost}/repos/${obj.user}/${obj.repo}/tarball/${obj.branch}` obj.clone_url = `https://${obj.host}/${obj.user}/${obj.repo}` if (obj.branch === 'master') { obj.https_url = `https://${obj.host}/${obj.user}/${obj.repo}` obj.travis_url = `https://travis-ci.org/${obj.user}/${obj.repo}` obj.zip_url = `https://${obj.host}/${obj.user}/${obj.repo}/archive/master.zip` } else { obj.https_url = `https://${obj.host}/${obj.user}/${obj.repo}/blob/${obj.branch}` obj.travis_url = `https://travis-ci.org/${obj.user}/${obj.repo}?branch=${obj.branch}` obj.zip_url = `https://${obj.host}/${obj.user}/${obj.repo}/archive/${obj.branch}.zip` } // Support deep paths (like lerna-style repos) if (obj.path) { obj.https_url += obj.path } obj.api_url = `https://${obj.apiHost}/repos/${obj.user}/${obj.repo}` return obj }