All files / bin npx-cli.js

100% Statements 48/48
100% Branches 29/29
100% Functions 2/2
100% Lines 48/48

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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129    6x     6x 6x     6x           6x           6x         6x 6x 816x   348x     6x                         6x                                   6x 6x 25x 25x 1x 24x 20x   20x   2x 2x     1x 1x     1x 1x       16x 4x 4x 1x   4x 4x 4x   12x     16x 6x 6x 6x 6x     16x     8x   2x   6x         4x 4x       6x 1x     6x  
#!/usr/bin/env node
 
const cli = require('../lib/cli.js')
 
// run the resulting command as `npm exec ...args`
process.argv[1] = require.resolve('./npm-cli.js')
process.argv.splice(2, 0, 'exec')
 
// TODO: remove the affordances for removed items in npm v9
const removedSwitches = new Set([
  'always-spawn',
  'ignore-existing',
  'shell-auto-fallback'
])
 
const removedOpts = new Set([
  'npm',
  'node-arg',
  'n'
])
 
const removed = new Set([
  ...removedSwitches,
  ...removedOpts
])
 
const { types, shorthands } = require('../lib/utils/config.js')
const npmSwitches = Object.entries(types)
  .filter(([key, type]) => type === Boolean ||
    (Array.isArray(type) && type.includes(Boolean)))
  .map(([key, type]) => key)
 
// things that don't take a value
const switches = new Set([
  ...removedSwitches,
  ...npmSwitches,
  'no-install',
  'quiet',
  'q',
  'version',
  'v',
  'help',
  'h'
])
 
// things that do take a value
const opts = new Set([
  ...removedOpts,
  'package',
  'p',
  'cache',
  'userconfig',
  'call',
  'c',
  'shell',
  'npm',
  'node-arg',
  'n'
])
 
// break out of loop when we find a positional argument or --
// If we find a positional arg, we shove -- in front of it, and
// let the normal npm cli handle the rest.
let i
let sawRemovedFlags = false
for (i = 3; i < process.argv.length; i++) {
  const arg = process.argv[i]
  if (arg === '--') {
    break
  } else if (/^-/.test(arg)) {
    const [key, ...v] = arg.replace(/^-+/, '').split('=')
 
    switch (key) {
      case 'p':
        process.argv[i] = ['--package', ...v].join('=')
        break
 
      case 'shell':
        process.argv[i] = ['--script-shell', ...v].join('=')
        break
 
      case 'no-install':
        process.argv[i] = '--yes=false'
        break
 
      default:
        // resolve shorthands and run again
        if (shorthands[key] && !removed.has(key)) {
          const a = [...shorthands[key]]
          if (v.length) {
            a.push(v.join('='))
          }
          process.argv.splice(i, 1, ...a)
          i--
          continue
        }
        break
    }
 
    if (removed.has(key)) {
      console.error(`npx: the --${key} argument has been removed.`)
      sawRemovedFlags = true
      process.argv.splice(i, 1)
      i--
    }
 
    if (v.length === 0 && !switches.has(key) &&
        (opts.has(key) || !/^-/.test(process.argv[i + 1]))) {
      // value will be next argument, skip over it.
      if (removed.has(key)) {
        // also remove the value for the cut key.
        process.argv.splice(i + 1, 1)
      } else {
        i++
      }
    }
  } else {
    // found a positional arg, put -- in front of it, and we're done
    process.argv.splice(i, 0, '--')
    break
  }
}
 
if (sawRemovedFlags) {
  console.error('See `npm help exec` for more information')
}
 
cli(process)