"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/npm/lib/view.js" (8 Mar 2017, 9269 Bytes) of archive /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 // npm view [pkg [pkg ...]]
    2 module.exports = view
    3 
    4 var npm = require('./npm.js')
    5 var readJson = require('read-package-json')
    6 var log = require('npmlog')
    7 var util = require('util')
    8 var semver = require('semver')
    9 var mapToRegistry = require('./utils/map-to-registry.js')
   10 var npa = require('npm-package-arg')
   11 var path = require('path')
   12 var usage = require('./utils/usage')
   13 
   14 view.usage = usage(
   15   'view',
   16   'npm view [<@scope>/]<pkg>[@<version>] [<field>[.subfield]...]'
   17 )
   18 
   19 view.completion = function (opts, cb) {
   20   if (opts.conf.argv.remain.length <= 2) {
   21     // FIXME: there used to be registry completion here, but it stopped making
   22     // sense somewhere around 50,000 packages on the registry
   23     return cb()
   24   }
   25   // have the package, get the fields.
   26   var tag = npm.config.get('tag')
   27   mapToRegistry(opts.conf.argv.remain[2], npm.config, function (er, uri, auth) {
   28     if (er) return cb(er)
   29 
   30     npm.registry.get(uri, { auth: auth }, function (er, d) {
   31       if (er) return cb(er)
   32       var dv = d.versions[d['dist-tags'][tag]]
   33       var fields = []
   34       d.versions = Object.keys(d.versions).sort(semver.compareLoose)
   35       fields = getFields(d).concat(getFields(dv))
   36       cb(null, fields)
   37     })
   38   })
   39 
   40   function getFields (d, f, pref) {
   41     f = f || []
   42     if (!d) return f
   43     pref = pref || []
   44     Object.keys(d).forEach(function (k) {
   45       if (k.charAt(0) === '_' || k.indexOf('.') !== -1) return
   46       var p = pref.concat(k).join('.')
   47       f.push(p)
   48       if (Array.isArray(d[k])) {
   49         d[k].forEach(function (val, i) {
   50           var pi = p + '[' + i + ']'
   51           if (val && typeof val === 'object') getFields(val, f, [p])
   52           else f.push(pi)
   53         })
   54         return
   55       }
   56       if (typeof d[k] === 'object') getFields(d[k], f, [p])
   57     })
   58     return f
   59   }
   60 }
   61 
   62 function view (args, silent, cb) {
   63   if (typeof cb !== 'function') {
   64     cb = silent
   65     silent = false
   66   }
   67 
   68   if (!args.length) args = ['.']
   69 
   70   var pkg = args.shift()
   71   var nv = npa(pkg)
   72   var name = nv.name
   73   var local = (name === '.' || !name)
   74 
   75   if (npm.config.get('global') && local) {
   76     return cb(new Error('Cannot use view command in global mode.'))
   77   }
   78 
   79   if (local) {
   80     var dir = npm.prefix
   81     readJson(path.resolve(dir, 'package.json'), function (er, d) {
   82       d = d || {}
   83       if (er && er.code !== 'ENOENT' && er.code !== 'ENOTDIR') return cb(er)
   84       if (!d.name) return cb(new Error('Invalid package.json'))
   85 
   86       var p = d.name
   87       nv = npa(p)
   88       if (pkg && ~pkg.indexOf('@')) {
   89         nv.rawSpec = pkg.split('@')[pkg.indexOf('@')]
   90       }
   91 
   92       fetchAndRead(nv, args, silent, cb)
   93     })
   94   } else {
   95     fetchAndRead(nv, args, silent, cb)
   96   }
   97 }
   98 
   99 function fetchAndRead (nv, args, silent, cb) {
  100   // get the data about this package
  101   var name = nv.name
  102   var version = nv.rawSpec || npm.config.get('tag')
  103 
  104   mapToRegistry(name, npm.config, function (er, uri, auth) {
  105     if (er) return cb(er)
  106 
  107     npm.registry.get(uri, { auth: auth }, function (er, data) {
  108       if (er) return cb(er)
  109       if (data['dist-tags'] && data['dist-tags'].hasOwnProperty(version)) {
  110         version = data['dist-tags'][version]
  111       }
  112 
  113       if (data.time && data.time.unpublished) {
  114         var u = data.time.unpublished
  115         er = new Error('Unpublished by ' + u.name + ' on ' + u.time)
  116         er.statusCode = 404
  117         er.code = 'E404'
  118         er.pkgid = data._id
  119         return cb(er, data)
  120       }
  121 
  122       var results = []
  123       var error = null
  124       var versions = data.versions || {}
  125       data.versions = Object.keys(versions).sort(semver.compareLoose)
  126       if (!args.length) args = ['']
  127 
  128       // remove readme unless we asked for it
  129       if (args.indexOf('readme') === -1) {
  130         delete data.readme
  131       }
  132 
  133       Object.keys(versions).forEach(function (v) {
  134         if (semver.satisfies(v, version, true)) {
  135           args.forEach(function (args) {
  136             // remove readme unless we asked for it
  137             if (args.indexOf('readme') !== -1) {
  138               delete versions[v].readme
  139             }
  140             results.push(showFields(data, versions[v], args))
  141           })
  142         }
  143       })
  144       results = results.reduce(reducer, {})
  145       var retval = results
  146 
  147       if (args.length === 1 && args[0] === '') {
  148         retval = cleanBlanks(retval)
  149         log.silly('cleanup', retval)
  150       }
  151 
  152       if (error || silent) cb(error, retval)
  153       else printData(results, data._id, cb.bind(null, error, retval))
  154     })
  155   })
  156 }
  157 
  158 function cleanBlanks (obj) {
  159   var clean = {}
  160   Object.keys(obj).forEach(function (version) {
  161     clean[version] = obj[version]['']
  162   })
  163   return clean
  164 }
  165 
  166 function reducer (l, r) {
  167   if (r) {
  168     Object.keys(r).forEach(function (v) {
  169       l[v] = l[v] || {}
  170       Object.keys(r[v]).forEach(function (t) {
  171         l[v][t] = r[v][t]
  172       })
  173     })
  174   }
  175 
  176   return l
  177 }
  178 
  179 // return whatever was printed
  180 function showFields (data, version, fields) {
  181   var o = {}
  182   ;[data, version].forEach(function (s) {
  183     Object.keys(s).forEach(function (k) {
  184       o[k] = s[k]
  185     })
  186   })
  187   return search(o, fields.split('.'), version.version, fields)
  188 }
  189 
  190 function search (data, fields, version, title) {
  191   var field
  192   var tail = fields
  193   while (!field && fields.length) field = tail.shift()
  194   fields = [field].concat(tail)
  195   var o
  196   if (!field && !tail.length) {
  197     o = {}
  198     o[version] = {}
  199     o[version][title] = data
  200     return o
  201   }
  202   var index = field.match(/(.+)\[([^\]]+)\]$/)
  203   if (index) {
  204     field = index[1]
  205     index = index[2]
  206     if (data.field && data.field.hasOwnProperty(index)) {
  207       return search(data[field][index], tail, version, title)
  208     } else {
  209       field = field + '[' + index + ']'
  210     }
  211   }
  212   if (Array.isArray(data)) {
  213     if (data.length === 1) {
  214       return search(data[0], fields, version, title)
  215     }
  216     var results = []
  217     data.forEach(function (data, i) {
  218       var tl = title.length
  219       var newt = title.substr(0, tl - fields.join('.').length - 1) +
  220                  '[' + i + ']' + [''].concat(fields).join('.')
  221       results.push(search(data, fields.slice(), version, newt))
  222     })
  223     results = results.reduce(reducer, {})
  224     return results
  225   }
  226   if (!data.hasOwnProperty(field)) return undefined
  227   data = data[field]
  228   if (tail.length) {
  229     if (typeof data === 'object') {
  230       // there are more fields to deal with.
  231       return search(data, tail, version, title)
  232     } else {
  233       return new Error('Not an object: ' + data)
  234     }
  235   }
  236   o = {}
  237   o[version] = {}
  238   o[version][title] = data
  239   return o
  240 }
  241 
  242 function printData (data, name, cb) {
  243   var versions = Object.keys(data)
  244   var msg = ''
  245   var msgJson = []
  246   var includeVersions = versions.length > 1
  247   var includeFields
  248 
  249   versions.forEach(function (v) {
  250     var fields = Object.keys(data[v])
  251     includeFields = includeFields || (fields.length > 1)
  252     if (npm.config.get('json')) msgJson.push({})
  253     fields.forEach(function (f) {
  254       var d = cleanup(data[v][f])
  255       if (fields.length === 1 && npm.config.get('json')) {
  256         msgJson[msgJson.length - 1][f] = d
  257       }
  258       if (includeVersions || includeFields || typeof d !== 'string') {
  259         if (npm.config.get('json')) {
  260           msgJson[msgJson.length - 1][f] = d
  261         } else {
  262           d = util.inspect(d, false, 5, npm.color)
  263         }
  264       } else if (typeof d === 'string' && npm.config.get('json')) {
  265         d = JSON.stringify(d)
  266       }
  267       if (!npm.config.get('json')) {
  268         if (f && includeFields) f += ' = '
  269         if (d.indexOf('\n') !== -1) d = ' \n' + d
  270         msg += (includeVersions ? name + '@' + v + ' ' : '') +
  271                (includeFields ? f : '') + d + '\n'
  272       }
  273     })
  274   })
  275 
  276   if (msgJson.length && Object.keys(msgJson[0]).length === 1) {
  277     var k = Object.keys(msgJson[0])[0]
  278     msgJson = msgJson.map(function (m) { return m[k] })
  279   }
  280 
  281   if (!msg) {
  282     msg = JSON.stringify(msgJson[0], null, 2) + '\n'
  283   } else if (msgJson.length > 1) {
  284     msg = JSON.stringify(msgJson, null, 2) + '\n'
  285   }
  286 
  287   // preserve output symmetry by adding a whitespace-only line at the end if
  288   // there's one at the beginning
  289   if (/^\s*\n/.test(msg)) msg += '\n'
  290 
  291   // disable the progress bar entirely, as we can't meaningfully update it if
  292   // we may have partial lines printed.
  293   log.disableProgress()
  294 
  295   // print directly to stdout to not unnecessarily add blank lines
  296   process.stdout.write(msg)
  297 
  298   cb(null, data)
  299 }
  300 function cleanup (data) {
  301   if (Array.isArray(data)) {
  302     return data.map(cleanup)
  303   }
  304   if (!data || typeof data !== 'object') return data
  305 
  306   if (typeof data.versions === 'object' &&
  307       data.versions &&
  308       !Array.isArray(data.versions)) {
  309     data.versions = Object.keys(data.versions || {})
  310   }
  311 
  312   var keys = Object.keys(data)
  313   keys.forEach(function (d) {
  314     if (d.charAt(0) === '_') delete data[d]
  315     else if (typeof data[d] === 'object') data[d] = cleanup(data[d])
  316   })
  317   keys = Object.keys(data)
  318   if (keys.length <= 3 &&
  319       data.name &&
  320       (keys.length === 1 ||
  321        keys.length === 3 && data.email && data.url ||
  322        keys.length === 2 && (data.email || data.url))) {
  323     data = unparsePerson(data)
  324   }
  325   return data
  326 }
  327 function unparsePerson (d) {
  328   if (typeof d === 'string') return d
  329   return d.name +
  330     (d.email ? ' <' + d.email + '>' : '') +
  331     (d.url ? ' (' + d.url + ')' : '')
  332 }