All files / lib repo.js

100% Statements 39/39
100% Branches 20/20
100% Functions 6/6
100% Lines 36/36

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 731x 1x 1x 1x 1x 1x 1x 1x   1x 1x   28x   1x 28x 1x   28x     1x 28x 28x   28x 28x         28x 2x         26x 26x   26x 2x         24x 24x     1x 14x         14x             12x 12x 12x   2x       1x  
const log = require('npmlog')
const pacote = require('pacote')
const { promisify } = require('util')
const openUrl = promisify(require('./utils/open-url.js'))
const usageUtil = require('./utils/usage.js')
const npm = require('./npm.js')
const hostedFromMani = require('./utils/hosted-git-info-from-manifest.js')
const { URL } = require('url')
 
const usage = usageUtil('repo', 'npm repo [<pkgname> [<pkgname> ...]]')
const completion = require('./utils/completion/none.js')
 
const cmd = (args, cb) => repo(args).then(() => cb()).catch(cb)
 
const repo = async args => {
  if (!args || !args.length) {
    args = ['.']
  }
  await Promise.all(args.map(pkg => getRepo(pkg)))
}
 
const getRepo = async pkg => {
  const opts = { ...npm.flatOptions, fullMetadata: true }
  const mani = await pacote.manifest(pkg, opts)
 
  const r = mani.repository
  const rurl = !r ? null
    : typeof r === 'string' ? r
    : typeof r === 'object' && typeof r.url === 'string' ? r.url
    : null
 
  if (!rurl) {
    throw Object.assign(new Error('no repository'), {
      pkgid: pkg
    })
  }
 
  const info = hostedFromMani(mani)
  const url = info ? info.browse() : unknownHostedUrl(rurl)
 
  if (!url) {
    throw Object.assign(new Error('no repository: could not get url'), {
      pkgid: pkg
    })
  }
 
  log.silly('docs', 'url', url)
  await openUrl(url, `${mani.name} repo available at the following URL`)
}
 
const unknownHostedUrl = url => {
  try {
    const {
      protocol,
      hostname,
      pathname
    } = new URL(url)
 
    /* istanbul ignore next - URL ctor should prevent this */
    if (!protocol || !hostname) {
      return null
    }
 
    const proto = /(git\+)http:$/.test(protocol) ? 'http:' : 'https:'
    const path = pathname.replace(/\.git$/, '')
    return `${proto}//${hostname}${path}`
  } catch (e) {
    return null
  }
}
 
module.exports = Object.assign(cmd, { usage, completion })