All files / lib/utils explain-dep.js

100% Statements 57/57
100% Branches 41/41
100% Functions 13/13
100% Lines 56/56

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 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 991x 1x 68x 15x 2x 2x 3x 3x     1x 14x     1x 31x 31x         31x     1x                 43x 43x 43x 43x 5x   43x 5x   43x 5x   43x 5x   43x       1x 31x 7x   24x 24x 32x     24x 3x 3x 3x 3x 18x 18x 18x 2x 2x   16x   3x 3x     24x 24x     1x 32x 32x         1x 32x 15x   17x       1x  
const chalk = require('chalk')
const nocolor = {
  bold: s => s,
  dim: s => s,
  red: s => s,
  yellow: s => s,
  cyan: s => s,
  magenta: s => s,
}
 
const explainNode = (node, depth, color) =>
  printNode(node, color) +
  explainDependents(node, depth, color)
 
const colorType = (type, color) => {
  const { red, yellow, cyan, magenta } = color ? chalk : nocolor
  const style = type === 'extraneous' ? red
    : type === 'dev' ? yellow
    : type === 'optional' ? cyan
    : type === 'peer' ? magenta
    : /* istanbul ignore next */ s => s
  return style(type)
}
 
const printNode = (node, color) => {
  const {
    name,
    version,
    location,
    extraneous,
    dev,
    optional,
    peer,
  } = node
  const { bold, dim } = color ? chalk : nocolor
  const extra = []
  if (extraneous)
    extra.push(' ' + bold(colorType('extraneous', color)))
 
  if (dev)
    extra.push(' ' + bold(colorType('dev', color)))
 
  if (optional)
    extra.push(' ' + bold(colorType('optional', color)))
 
  if (peer)
    extra.push(' ' + bold(colorType('peer', color)))
 
  return `${bold(name)}@${bold(version)}${extra.join('')}` +
    (location ? dim(`\n${location}`) : '')
}
 
const explainDependents = ({ name, dependents }, depth, color) => {
  if (!dependents || !dependents.length || depth <= 0)
    return ''
 
  const max = Math.ceil(depth / 2)
  const messages = dependents.slice(0, max)
    .map(edge => explainEdge(edge, depth, color))
 
  // show just the names of the first 5 deps that overflowed the list
  if (dependents.length > max) {
    let len = 0
    const maxLen = 50
    const showNames = []
    for (let i = max; i < dependents.length; i++) {
      const { from: { name = 'the root project' } } = dependents[i]
      len += name.length
      if (len >= maxLen && i < dependents.length - 1) {
        showNames.push('...')
        break
      }
      showNames.push(name)
    }
    const show = `(${showNames.join(', ')})`
    messages.push(`${dependents.length - max} more ${show}`)
  }
 
  const str = '\n' + messages.join('\n')
  return str.split('\n').join('\n  ')
}
 
const explainEdge = ({ name, type, from, spec }, depth, color) => {
  const { bold } = color ? chalk : nocolor
  return (type === 'prod' ? '' : `${colorType(type, color)} `) +
    `${bold(name)}@"${bold(spec)}" from ` +
    explainFrom(from, depth, color)
}
 
const explainFrom = (from, depth, color) => {
  if (!from.name && !from.version)
    return 'the root project'
 
  return printNode(from, color) +
    explainDependents(from, depth - 1, color)
}
 
module.exports = { explainNode, printNode, explainEdge }