function fetchVersions (options, nameVersion) {
    // console.log(nameVersion);
    // TODO use check.schema
  check.verify.object(nameVersion, 'expected name, version object')
  var name = nameVersion.name
  var version = nameVersion.version
  check.verify.string(name, 'missing name string')
  check.verify.string(version, 'missing version string')

  var cleanVersionForName = _.partial(cleanVersionFor, name)
  function isLaterVersion (ver) {
    var later = semver.gt(ver, version)
    return later
  }

    // console.log('fetching versions for', name, 'current version', version);
  var MAX_WAIT_TIMEOUT = options.checkVersionTimeout || 25000
  var deferred = q.defer()

  function rejectOnTimeout () {
    var msg = 'timed out waiting for NPM for package ' + name +
            ' after ' + MAX_WAIT_TIMEOUT + 'ms'
    console.error(msg)
    deferred.reject(msg)
  }

  function escapeName (str) {
    return str.replace('/', '%2F')
  }

  registryUrl().then(function (npmUrl) {
    log('NPM registry url', npmUrl)
    la(check.webUrl(npmUrl), 'need npm registry url, got', npmUrl)

    npmUrl = npmUrl.replace(/^https:/, 'http:').trim()
    var url = (options.registry || npmUrl) + escapeName(name)

        // TODO how to detect if the registry is not responding?

    log('getting url', url)
    request.get(url, onNPMversions)
    var timer = setTimeout(rejectOnTimeout, MAX_WAIT_TIMEOUT)

    function onNPMversions (err, response, body) {
      log('got response for', url)
      clearTimeout(timer)

      if (err) {
        console.error('ERROR when fetching info for package', name)
        deferred.reject(err.message)
        return
      }

      if (is404(response)) {
        log('404 response for', url)
        deferred.resolve({
          name: name,
          versions: []
        })
        return
      }

      try {
        log('parsing response body')
        var info = JSON.parse(body)
        log('parsed response, error?', info.error)
        if (info.error) {
          log('error parsing\n' + body + '\n')
          var str = formNpmErrorMessage(name, info)
          console.error(str)

          if (isNotFound(info.error)) {
            deferred.resolve({
              name: name,
              versions: []
            })
            return
          }

          deferred.reject(str)
          return
        }
        log('extracting versions')
        var versions = extractVersions(info)
        log('%d versions', versions.length)

        if (!Array.isArray(versions)) {
          throw new Error('Could not get versions for ' + name +
                        ' from ' + JSON.stringify(info) +
                        ' response ' + JSON.stringify(response, null, 2))
        }

        var validVersions = versions.filter(cleanVersionForName)
        var newerVersions = validVersions.filter(isLaterVersion)
        log('%d valid versions', validVersions.length)
        if (validVersions.length) {
          log('last version %s', R.last(validVersions))
        }
        if (newerVersions.length) {
          log('%d newer versions', newerVersions.length)
          log('from %s to %s', R.head(newerVersions), R.last(newerVersions))
        }

        deferred.resolve({
          name: name,
          versions: newerVersions
        })
        return
      } catch (err) {
        console.error(err)
        deferred.reject('Could not fetch versions for ' + name)
      }
    }
  })

  return deferred.promise
}
function fetchVersions (options, nameVersion) {
    
    
  check.verify.object(nameVersion, 'expected name, version object')
  var name = nameVersion.name
  var version = nameVersion.version
  check.verify.string(name, 'missing name string')
  check.verify.string(version, 'missing version string')

  var cleanVersionForName = _.partial(cleanVersionFor, name)
  function isLaterVersion (ver) {
    var later = semver.gt(ver, version)
    return later
  }

    
  var MAX_WAIT_TIMEOUT = options.checkVersionTimeout || 25000
  var deferred = q.defer()

  function rejectOnTimeout () {
    var msg = 'timed out waiting for NPM for package ' + name +
            ' after ' + MAX_WAIT_TIMEOUT + 'ms'
    console.error(msg)
    deferred.reject(msg)
  }

  function escapeName (str) {
    return str.replace('/', '%2F')
  }

  registryUrl().then(function (npmUrl) {
    log('NPM registry url', npmUrl)
    la(check.webUrl(npmUrl), 'need npm registry url, got', npmUrl)

    npmUrl = npmUrl.replace(/^https:/, 'http:').trim()
    var url = (options.registry || npmUrl) + escapeName(name)

        

    log('getting url', url)
    request.get(url, onNPMversions)
    var timer = setTimeout(rejectOnTimeout, MAX_WAIT_TIMEOUT)

    function onNPMversions (err, response, body) {
      log('got response for', url)
      clearTimeout(timer)

      if (err) {
        console.error('ERROR when fetching info for package', name)
        deferred.reject(err.message)
        return
      }

      if (is404(response)) {
        log('404 response for', url)
        deferred.resolve({
          name: name,
          versions: []
        })
        return
      }

      try {
        log('parsing response body')
        var info = JSON.parse(body)
        log('parsed response, error?', info.error)
        if (info.error) {
          log('error parsing\n' + body + '\n')
          var str = formNpmErrorMessage(name, info)
          console.error(str)

          if (isNotFound(info.error)) {
            deferred.resolve({
              name: name,
              versions: []
            })
            return
          }

          deferred.reject(str)
          return
        }
        log('extracting versions')
        var versions = extractVersions(info)
        log('%d versions', versions.length)

        if (!Array.isArray(versions)) {
          throw new Error('Could not get versions for ' + name +
                        ' from ' + JSON.stringify(info) +
                        ' response ' + JSON.stringify(response, null, 2))
        }

        var validVersions = versions.filter(cleanVersionForName)
        var newerVersions = validVersions.filter(isLaterVersion)
        log('%d valid versions', validVersions.length)
        if (validVersions.length) {
          log('last version %s', R.last(validVersions))
        }
        if (newerVersions.length) {
          log('%d newer versions', newerVersions.length)
          log('from %s to %s', R.head(newerVersions), R.last(newerVersions))
        }

        deferred.resolve({
          name: name,
          versions: newerVersions
        })
        return
      } catch (err) {
        console.error(err)
        deferred.reject('Could not fetch versions for ' + name)
      }
    }
  })

  return deferred.promise
}
function fetchVersions ( options , nameVersion ) { // console.log(nameVersion); // TODO use check.schema check . verify . object ( nameVersion , 'expected name, version object' ) var name = nameVersion . name var version = nameVersion . version check . verify . string ( name , 'missing name string' ) check . verify . string ( version , 'missing version string' ) var cleanVersionForName = _ . partial ( cleanVersionFor , name ) function isLaterVersion ( ver ) { var later = semver . gt ( ver , version ) return later } // console.log('fetching versions for', name, 'current version', version); var MAX_WAIT_TIMEOUT = options . checkVersionTimeout || 25000 var deferred = q . defer ( ) function rejectOnTimeout ( ) { var msg = 'timed out waiting for NPM for package ' + name + ' after ' + MAX_WAIT_TIMEOUT + 'ms' console . error ( msg ) deferred . reject ( msg ) } function escapeName ( str ) { return str . replace ( '/' , '%2F' ) } registryUrl ( ) . then ( function ( npmUrl ) { log ( 'NPM registry url' , npmUrl ) la ( check . webUrl ( npmUrl ) , 'need npm registry url, got' , npmUrl ) npmUrl = npmUrl . replace ( / ^https: / , 'http:' ) . trim ( ) var url = ( options . registry || npmUrl ) + escapeName ( name ) // TODO how to detect if the registry is not responding? log ( 'getting url' , url ) request . get ( url , onNPMversions ) var timer = setTimeout ( rejectOnTimeout , MAX_WAIT_TIMEOUT ) function onNPMversions ( err , response , body ) { log ( 'got response for' , url ) clearTimeout ( timer ) if ( err ) { console . error ( 'ERROR when fetching info for package' , name ) deferred . reject ( err . message ) return } if ( is404 ( response ) ) { log ( '404 response for' , url ) deferred . resolve ( { name : name , versions : [ ] } ) return } try { log ( 'parsing response body' ) var info = JSON . parse ( body ) log ( 'parsed response, error?' , info . error ) if ( info . error ) { log ( 'error parsing\n' + body + '\n' ) var str = formNpmErrorMessage ( name , info ) console . error ( str ) if ( isNotFound ( info . error ) ) { deferred . resolve ( { name : name , versions : [ ] } ) return } deferred . reject ( str ) return } log ( 'extracting versions' ) var versions = extractVersions ( info ) log ( '%d versions' , versions . length ) if ( ! Array . isArray ( versions ) ) { throw new Error ( 'Could not get versions for ' + name + ' from ' + JSON . stringify ( info ) + ' response ' + JSON . stringify ( response , null , 2 ) ) } var validVersions = versions . filter ( cleanVersionForName ) var newerVersions = validVersions . filter ( isLaterVersion ) log ( '%d valid versions' , validVersions . length ) if ( validVersions . length ) { log ( 'last version %s' , R . last ( validVersions ) ) } if ( newerVersions . length ) { log ( '%d newer versions' , newerVersions . length ) log ( 'from %s to %s' , R . head ( newerVersions ) , R . last ( newerVersions ) ) } deferred . resolve ( { name : name , versions : newerVersions } ) return } catch ( err ) { console . error ( err ) deferred . reject ( 'Could not fetch versions for ' + name ) } } } ) return deferred . promise }
fetching versions inspired by https://github.com/jprichardson/npm-latest returns a promise
fetching versions inspired by https : // github . com / jprichardson / npm - latest returns a promise