File Explorer

/var/lang/lib/node_modules/npm/lib/utils

This explorer reads the filesystem of the server it runs on, so /workspace/user isn't present here. Browsing and the terminal still work against this server's own disk from /.

0 dirs
35 files
format-search-stream.js4.8 KB · 174 lines
const { stripVTControlCharacters: strip } = require('node:util')const { Minipass } = require('minipass') // This module consumes package data in the following format://// {//   name: String,//   description: String,//   maintainers: [{ username: String, email: String }],//   keywords: String | [String],//   version: String,//   date: Date // can be null,// }//// The returned stream will format this package data// into a byte stream of formatted, displayable output. function filter (data, exclude) {  const words = [data.name]    .concat(data.maintainers.map(m => m.username))    .concat(data.keywords || [])    .map(f => f?.trim?.())    .filter(Boolean)    .join(' ')    .toLowerCase()   if (exclude.find(pattern => {    // Treats both /foo and /foo/ as regex searches    if (pattern.startsWith('/')) {      if (pattern.endsWith('/')) {        pattern = pattern.slice(0, -1)      }      return words.match(new RegExp(pattern.slice(1)))    }    return words.includes(pattern)  })) {    return false  }   return true} module.exports = (opts) => {  return opts.json ? new JSONOutputStream(opts) : new TextOutputStream(opts)} class JSONOutputStream extends Minipass {  #didFirst = false  #exclude   constructor (opts) {    super()    this.#exclude = opts.exclude  }   write (obj) {    if (!filter(obj, this.#exclude)) {      return    }    if (!this.#didFirst) {      super.write('[\n')      this.#didFirst = true    } else {      super.write('\n,\n')    }     return super.write(JSON.stringify(obj))  }   end () {    super.write(this.#didFirst ? ']\n' : '\n[]\n')    super.end()  }} class TextOutputStream extends Minipass {  #args  #chalk  #exclude  #parseable   constructor (opts) {    super()    // Consider a search for "cowboys" and "boy".  If we highlight "boys" first the "cowboys" string will no longer string match because of the ansi highlighting added to "boys".  If we highlight "boy" second then the ansi reset at the end will make the highlighting only on "cowboy" with a normal "s".  Neither is perfect but at least the first option doesn't do partial highlighting. So, we sort strings smaller to larger    this.#args = opts.args      .map(s => s.toLowerCase())      .filter(Boolean)      .sort((a, b) => a.length - b.length)    this.#chalk = opts.npm.chalk    this.#exclude = opts.exclude    this.#parseable = opts.parseable  }   write (data) {    if (!filter(data, this.#exclude)) {      return    }    // Normalize    const pkg = {      authors: data.maintainers.map((m) => `${strip(m.username)}`).join(' '),      publisher: strip(data.publisher?.username || ''),      date: data.date ? data.date.toISOString().slice(0, 10) : 'prehistoric',      description: strip(data.description ?? ''),      keywords: [],      name: strip(data.name),      version: data.version,    }    if (Array.isArray(data.keywords)) {      pkg.keywords = data.keywords.map(strip)    } else if (typeof data.keywords === 'string') {      pkg.keywords = strip(data.keywords.replace(/[,\s]+/, ' ')).split(' ')    }     let output    if (this.#parseable) {      output = [pkg.name, pkg.description, pkg.author, pkg.date, pkg.version, pkg.keywords]        .filter(Boolean)        .map(col => ('' + col).replace(/\t/g, ' ')).join('\t')      return super.write(output)    }     const keywords = pkg.keywords.map(k => {      if (this.#args.includes(k)) {        return this.#chalk.cyan(k)      } else {        return k      }    }).join(' ')     const description = this.#highlight(pkg.description)    let name    if (this.#args.includes(pkg.name)) {      name = this.#chalk.cyan(pkg.name)    } else {      name = this.#highlight(pkg.name)      name = this.#chalk.blue(name)    }     if (description.length) {      output = `${name}\n${description}\n`    } else {      output = `${name}\n`    }    if (pkg.publisher) {      output += `Version ${this.#chalk.blue(pkg.version)} published ${this.#chalk.blue(pkg.date)} by ${this.#chalk.blue(pkg.publisher)}\n`    } else {      output += `Version ${this.#chalk.blue(pkg.version)} published ${this.#chalk.blue(pkg.date)} by ${this.#chalk.yellow('???')}\n`    }    output += `Maintainers: ${pkg.authors}\n`    if (keywords) {      output += `Keywords: ${keywords}\n`    }    output += `${this.#chalk.blue(`https://npm.im/${pkg.name}`)}\n`    return super.write(output)  }   #highlight (input) {    let output = input    for (const arg of this.#args) {      let i = output.toLowerCase().indexOf(arg)      while (i > -1) {        const highlit = this.#chalk.cyan(output.slice(i, i + arg.length))        output = [          output.slice(0, i),          highlit,          output.slice(i + arg.length),        ].join('')        i = output.toLowerCase().indexOf(arg, i + highlit.length)      }    }    return output  }}