"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/npm/lib/search.js" (8 Mar 2017, 7944 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 
    2 module.exports = exports = search
    3 
    4 var npm = require('./npm.js')
    5 var columnify = require('columnify')
    6 var updateIndex = require('./cache/update-index.js')
    7 var usage = require('./utils/usage')
    8 var output = require('./utils/output.js')
    9 
   10 search.usage = usage(
   11   'search',
   12   'npm search [--long] [search terms ...]'
   13 )
   14 
   15 search.completion = function (opts, cb) {
   16   var compl = {}
   17   var partial = opts.partialWord
   18   var ipartial = partial.toLowerCase()
   19   var plen = partial.length
   20 
   21   // get the batch of data that matches so far.
   22   // this is an example of using npm.commands.search programmatically
   23   // to fetch data that has been filtered by a set of arguments.
   24   search(opts.conf.argv.remain.slice(2), true, function (er, data) {
   25     if (er) return cb(er)
   26     Object.keys(data).forEach(function (name) {
   27       data[name].words.split(' ').forEach(function (w) {
   28         if (w.toLowerCase().indexOf(ipartial) === 0) {
   29           compl[partial + w.substr(plen)] = true
   30         }
   31       })
   32     })
   33     cb(null, Object.keys(compl))
   34   })
   35 }
   36 
   37 function search (args, silent, staleness, cb) {
   38   if (typeof cb !== 'function') {
   39     cb = staleness
   40     staleness = 600
   41   }
   42   if (typeof cb !== 'function') {
   43     cb = silent
   44     silent = false
   45   }
   46 
   47   var searchopts = npm.config.get('searchopts')
   48   var searchexclude = npm.config.get('searchexclude')
   49 
   50   if (typeof searchopts !== 'string') searchopts = ''
   51   searchopts = searchopts.split(/\s+/)
   52   var opts = searchopts.concat(args).map(function (s) {
   53     return s.toLowerCase()
   54   }).filter(function (s) { return s })
   55 
   56   if (opts.length === 0) {
   57     return cb(new Error('search must be called with arguments'))
   58   }
   59 
   60   if (typeof searchexclude === 'string') {
   61     searchexclude = searchexclude.split(/\s+/)
   62   } else {
   63     searchexclude = []
   64   }
   65   searchexclude = searchexclude.map(function (s) {
   66     return s.toLowerCase()
   67   })
   68 
   69   getFilteredData(staleness, opts, searchexclude, function (er, data) {
   70     // now data is the list of data that we want to show.
   71     // prettify and print it, and then provide the raw
   72     // data to the cb.
   73     if (er || silent) return cb(er, data)
   74     output(prettify(data, args))
   75     cb(null, data)
   76   })
   77 }
   78 
   79 function getFilteredData (staleness, args, notArgs, cb) {
   80   updateIndex(staleness, function (er, data) {
   81     if (er) return cb(er)
   82     return cb(null, filter(data, args, notArgs))
   83   })
   84 }
   85 
   86 function filter (data, args, notArgs) {
   87   // data={<name>:{package data}}
   88   return Object.keys(data).map(function (d) {
   89     return data[d]
   90   }).filter(function (d) {
   91     return typeof d === 'object'
   92   }).map(stripData).map(getWords).filter(function (data) {
   93     return filterWords(data, args, notArgs)
   94   }).reduce(function (l, r) {
   95     l[r.name] = r
   96     return l
   97   }, {})
   98 }
   99 
  100 function stripData (data) {
  101   return {
  102     name: data.name,
  103     description: npm.config.get('description') ? data.description : '',
  104     maintainers: (data.maintainers || []).map(function (m) {
  105       return '=' + m.name
  106     }),
  107     url: !Object.keys(data.versions || {}).length ? data.url : null,
  108     keywords: data.keywords || [],
  109     version: Object.keys(data.versions || {})[0] || [],
  110     time: data.time &&
  111           data.time.modified &&
  112           (new Date(data.time.modified).toISOString() // remove time
  113             .split('T').join(' ')
  114             .replace(/:[0-9]{2}\.[0-9]{3}Z$/, ''))
  115             .slice(0, -5) ||
  116           'prehistoric'
  117   }
  118 }
  119 
  120 function getWords (data) {
  121   data.words = [ data.name ]
  122                .concat(data.description)
  123                .concat(data.maintainers)
  124                .concat(data.url && ('<' + data.url + '>'))
  125                .concat(data.keywords)
  126                .map(function (f) { return f && f.trim && f.trim() })
  127                .filter(function (f) { return f })
  128                .join(' ')
  129                .toLowerCase()
  130   return data
  131 }
  132 
  133 function filterWords (data, args, notArgs) {
  134   var words = data.words
  135   for (var i = 0, l = args.length; i < l; i++) {
  136     if (!match(words, args[i])) return false
  137   }
  138   for (i = 0, l = notArgs.length; i < l; i++) {
  139     if (match(words, notArgs[i])) return false
  140   }
  141   return true
  142 }
  143 
  144 function match (words, arg) {
  145   if (arg.charAt(0) === '/') {
  146     arg = arg.replace(/\/$/, '')
  147     arg = new RegExp(arg.substr(1, arg.length - 1))
  148     return words.match(arg)
  149   }
  150   return words.indexOf(arg) !== -1
  151 }
  152 
  153 function prettify (data, args) {
  154   var searchsort = (npm.config.get('searchsort') || 'NAME').toLowerCase()
  155   var sortField = searchsort.replace(/^\-+/, '')
  156   var searchRev = searchsort.charAt(0) === '-'
  157   var truncate = !npm.config.get('long')
  158 
  159   if (Object.keys(data).length === 0) {
  160     return 'No match found for ' + (args.map(JSON.stringify).join(' '))
  161   }
  162 
  163   var lines = Object.keys(data).map(function (d) {
  164     // strip keyname
  165     return data[d]
  166   }).map(function (dat) {
  167     dat.author = dat.maintainers
  168     delete dat.maintainers
  169     dat.date = dat.time
  170     delete dat.time
  171     return dat
  172   }).map(function (dat) {
  173     // split keywords on whitespace or ,
  174     if (typeof dat.keywords === 'string') {
  175       dat.keywords = dat.keywords.split(/[,\s]+/)
  176     }
  177     if (Array.isArray(dat.keywords)) {
  178       dat.keywords = dat.keywords.join(' ')
  179     }
  180 
  181     // split author on whitespace or ,
  182     if (typeof dat.author === 'string') {
  183       dat.author = dat.author.split(/[,\s]+/)
  184     }
  185     if (Array.isArray(dat.author)) {
  186       dat.author = dat.author.join(' ')
  187     }
  188     return dat
  189   })
  190 
  191   lines.sort(function (a, b) {
  192     var aa = a[sortField].toLowerCase()
  193     var bb = b[sortField].toLowerCase()
  194     return aa === bb ? 0
  195          : aa < bb ? -1 : 1
  196   })
  197 
  198   if (searchRev) lines.reverse()
  199 
  200   var columns = npm.config.get('description')
  201                ? ['name', 'description', 'author', 'date', 'version', 'keywords']
  202                : ['name', 'author', 'date', 'version', 'keywords']
  203 
  204   var output = columnify(
  205     lines,
  206     {
  207       include: columns,
  208       truncate: truncate,
  209       config: {
  210         name: { maxWidth: 40, truncate: false, truncateMarker: '' },
  211         description: { maxWidth: 60 },
  212         author: { maxWidth: 20 },
  213         date: { maxWidth: 11 },
  214         version: { maxWidth: 11 },
  215         keywords: { maxWidth: Infinity }
  216       }
  217     }
  218   )
  219   output = trimToMaxWidth(output)
  220   output = highlightSearchTerms(output, args)
  221 
  222   return output
  223 }
  224 
  225 var colors = [31, 33, 32, 36, 34, 35]
  226 var cl = colors.length
  227 
  228 function addColorMarker (str, arg, i) {
  229   var m = i % cl + 1
  230   var markStart = String.fromCharCode(m)
  231   var markEnd = String.fromCharCode(0)
  232 
  233   if (arg.charAt(0) === '/') {
  234     return str.replace(
  235       new RegExp(arg.substr(1, arg.length - 2), 'gi'),
  236       function (bit) { return markStart + bit + markEnd }
  237     )
  238   }
  239 
  240   // just a normal string, do the split/map thing
  241   var pieces = str.toLowerCase().split(arg.toLowerCase())
  242   var p = 0
  243 
  244   return pieces.map(function (piece) {
  245     piece = str.substr(p, piece.length)
  246     var mark = markStart +
  247                str.substr(p + piece.length, arg.length) +
  248                markEnd
  249     p += piece.length + arg.length
  250     return piece + mark
  251   }).join('')
  252 }
  253 
  254 function colorize (line) {
  255   for (var i = 0; i < cl; i++) {
  256     var m = i + 1
  257     var color = npm.color ? '\u001B[' + colors[i] + 'm' : ''
  258     line = line.split(String.fromCharCode(m)).join(color)
  259   }
  260   var uncolor = npm.color ? '\u001B[0m' : ''
  261   return line.split('\u0000').join(uncolor)
  262 }
  263 
  264 function getMaxWidth () {
  265   var cols
  266   try {
  267     var tty = require('tty')
  268     var stdout = process.stdout
  269     cols = !tty.isatty(stdout.fd) ? Infinity : process.stdout.getWindowSize()[0]
  270     cols = (cols === 0) ? Infinity : cols
  271   } catch (ex) { cols = Infinity }
  272   return cols
  273 }
  274 
  275 function trimToMaxWidth (str) {
  276   var maxWidth = getMaxWidth()
  277   return str.split('\n').map(function (line) {
  278     return line.slice(0, maxWidth)
  279   }).join('\n')
  280 }
  281 
  282 function highlightSearchTerms (str, terms) {
  283   terms.forEach(function (arg, i) {
  284     str = addColorMarker(str, arg, i)
  285   })
  286 
  287   return colorize(str).trim()
  288 }