codekingpro/portable-devtools
114k
1const Pipeline = require('minipass-pipeline')
2const libSearch = require('libnpmsearch')
3const { log, output } = require('proc-log')
4const formatSearchStream = require('../utils/format-search-stream.js')
5const BaseCommand = require('../base-cmd.js')
6
7class Search extends BaseCommand {
8 static description = 'Search for packages'
9 static name = 'search'
10 static params = [
11 'json',
12 'color',
13 'parseable',
14 'description',
15 'searchlimit',
16 'searchopts',
17 'searchexclude',
18 'registry',
19 'prefer-online',
20 'prefer-offline',
21 'offline',
22 ]
23
24 static usage = ['<search term> [<search term> ...]']
25
26 async exec (args) {
27 const opts = {
28 ...this.npm.flatOptions,
29 ...this.npm.flatOptions.search,
30 include: args.map(s => s.toLowerCase()).filter(Boolean),
31 exclude: this.npm.flatOptions.search.exclude.split(/\s+/),
32 }
33
34 if (opts.include.length === 0) {
35 throw new Error('search must be called with arguments')
36 }
37
38 // Used later to figure out whether we had any packages go out
39 let anyOutput = false
40
41 // Grab a configured output stream that will spit out packages in the desired format.
42 const outputStream = formatSearchStream({
43 args, // --searchinclude options are not highlighted
44 ...opts,
45 npm: this.npm,
46 })
47
48 log.silly('search', 'searching packages')
49 const p = new Pipeline(
50 libSearch.stream(opts.include, opts),
51 outputStream
52 )
53
54 p.on('data', chunk => {
55 if (!anyOutput) {
56 anyOutput = true
57 }
58 output.standard(chunk.toString('utf8'))
59 })
60
61 await p.promise()
62 if (!anyOutput && !this.npm.config.get('json') && !this.npm.config.get('parseable')) {
63 output.standard('No matches found for ' + (args.map(JSON.stringify).join(' ')))
64 }
65
66 log.silly('search', 'search completed')
67 }
68}
69
70module.exports = Search
71 