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 721x 1x 1x 1x 1x 1x 1x 1x   1x 1x   29x   1x 29x 1x   29x     1x 29x 29x   29x 29x         29x 2x         27x 27x   27x 2x         25x 25x     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(mani.repository.directory) : 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 })