<fim-prefix> urls can contain @
  // Also, in some cases we get [name, null] rather
  // that just a single argument.

  var usage = 'Usage:\n' +
              '    npm cache add <tarball-url>\n' +
              '    npm cache add <pkg>@<ver>\n' +
              '    npm cache add <tarball>\n' +
              '    npm cache add <folder>\n'
  var spec

  log.silly('cache add', 'args', args)

  if (args[1] === undefined) args[1] = null

  // at this point the args length must ==2
  if (args[1] !== null) {
    spec = args[0] + '@' + args[1]
  } else if (args.length === 2) {
    spec = args[0]
  }

  log.verbose('cache add', 'spec', spec)

  if (!spec) return cb(usage)

  adding++
  cb = afterAdd(cb)

  realizePackageSpecifier(spec, where, function (err, p) {
    if (err) return cb(err)

    log.silly('cache add', 'parsed spec', p)

    switch (p.type) {
      case 'local':
      case 'directory':
        addLocal(p, null, cb)
        break
      case 'remote':
        // get auth, if possible
        // BUG: CWE-200 Exposure of Sensitive Information to an Unauthorized Actor
        // mapToRegistry(spec, npm.config, function (err, uri, auth) {
        // FIXED:
 <fim-middle>       mapToRegistry(p.raw, npm.config, function (err, uri, auth) {
          if (err) return cb(err)

          addRemoteTarball(p.spec, { name: p.name }, null, auth, cb)
        })
        break
    <fix-suffix>  case 'git':
      case 'hosted':
        addRemoteGit(p.rawSpec, cb)
        break
      default:
        if (p.name) return addNamed(p.name, p.spec, null, cb)

        cb(new Error("couldn't figure out how to install " + spec))
    }
  })
}

function unpack (pkg, ver, unpackTarget, dMode, fMode, uid, gid, cb) {
  if (typeof cb !== 'function') {
    cb = gid
    gid = null
  }
  if (typeof cb !== 'function') {
    cb = uid
    uid = null
  }
  if (typeof cb !== 'function') {
    cb = fMode
    fMode = null
  }
  if (typeof cb !== 'function') {
    cb = dMode
    dMode = null
  }

  read(pkg, ver, false, function (er) {
    if (er) {
      log.error('unpack', 'Could not read data for %s', pkg + '@' + ver)
      return cb(er)
    }
    npm.commands.unbuild([unpackTarget], true, function (er) {
      if (er) return cb(er)
      tar.unpack(
        path.join(cachedPackageRoot({ name: pkg, version: ver }), 'package.tgz'),
        unpackTarget,
        dMode, fMode,
        uid, gid,
     <|endoftext|>