nl_tokens: fetching versions inspired by https : // github . com / jprichardson / npm - latest returns a promise
pl_tokens: 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 ( <mask> , 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 }