11cb0ef41Sopenharmony_ciconst { stripVTControlCharacters } = require('node:util') 21cb0ef41Sopenharmony_ciconst { Minipass } = require('minipass') 31cb0ef41Sopenharmony_ciconst columnify = require('columnify') 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci// This module consumes package data in the following format: 61cb0ef41Sopenharmony_ci// 71cb0ef41Sopenharmony_ci// { 81cb0ef41Sopenharmony_ci// name: String, 91cb0ef41Sopenharmony_ci// description: String, 101cb0ef41Sopenharmony_ci// maintainers: [{ username: String, email: String }], 111cb0ef41Sopenharmony_ci// keywords: String | [String], 121cb0ef41Sopenharmony_ci// version: String, 131cb0ef41Sopenharmony_ci// date: Date // can be null, 141cb0ef41Sopenharmony_ci// } 151cb0ef41Sopenharmony_ci// 161cb0ef41Sopenharmony_ci// The returned stream will format this package data 171cb0ef41Sopenharmony_ci// into a byte stream of formatted, displayable output. 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_cimodule.exports = async (opts) => { 201cb0ef41Sopenharmony_ci return opts.json ? new JSONOutputStream() : new TextOutputStream(opts) 211cb0ef41Sopenharmony_ci} 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ciclass JSONOutputStream extends Minipass { 241cb0ef41Sopenharmony_ci #didFirst = false 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ci write (obj) { 271cb0ef41Sopenharmony_ci if (!this.#didFirst) { 281cb0ef41Sopenharmony_ci super.write('[\n') 291cb0ef41Sopenharmony_ci this.#didFirst = true 301cb0ef41Sopenharmony_ci } else { 311cb0ef41Sopenharmony_ci super.write('\n,\n') 321cb0ef41Sopenharmony_ci } 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci return super.write(JSON.stringify(obj)) 351cb0ef41Sopenharmony_ci } 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_ci end () { 381cb0ef41Sopenharmony_ci super.write(this.#didFirst ? ']\n' : '\n[]\n') 391cb0ef41Sopenharmony_ci super.end() 401cb0ef41Sopenharmony_ci } 411cb0ef41Sopenharmony_ci} 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ciclass TextOutputStream extends Minipass { 441cb0ef41Sopenharmony_ci #opts 451cb0ef41Sopenharmony_ci #line = 0 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci constructor (opts) { 481cb0ef41Sopenharmony_ci super() 491cb0ef41Sopenharmony_ci this.#opts = opts 501cb0ef41Sopenharmony_ci } 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci write (pkg) { 531cb0ef41Sopenharmony_ci return super.write(this.#prettify(pkg)) 541cb0ef41Sopenharmony_ci } 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci #prettify (data) { 571cb0ef41Sopenharmony_ci const pkg = { 581cb0ef41Sopenharmony_ci author: data.maintainers.map((m) => `=${stripVTControlCharacters(m.username)}`).join(' '), 591cb0ef41Sopenharmony_ci date: 'prehistoric', 601cb0ef41Sopenharmony_ci description: stripVTControlCharacters(data.description ?? ''), 611cb0ef41Sopenharmony_ci keywords: '', 621cb0ef41Sopenharmony_ci name: stripVTControlCharacters(data.name), 631cb0ef41Sopenharmony_ci version: data.version, 641cb0ef41Sopenharmony_ci } 651cb0ef41Sopenharmony_ci if (Array.isArray(data.keywords)) { 661cb0ef41Sopenharmony_ci pkg.keywords = data.keywords.map((k) => stripVTControlCharacters(k)).join(' ') 671cb0ef41Sopenharmony_ci } else if (typeof data.keywords === 'string') { 681cb0ef41Sopenharmony_ci pkg.keywords = stripVTControlCharacters(data.keywords.replace(/[,\s]+/, ' ')) 691cb0ef41Sopenharmony_ci } 701cb0ef41Sopenharmony_ci if (data.date) { 711cb0ef41Sopenharmony_ci pkg.date = data.date.toISOString().split('T')[0] // remove time 721cb0ef41Sopenharmony_ci } 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci const columns = ['name', 'description', 'author', 'date', 'version', 'keywords'] 751cb0ef41Sopenharmony_ci if (this.#opts.parseable) { 761cb0ef41Sopenharmony_ci return columns.map((col) => pkg[col] && ('' + pkg[col]).replace(/\t/g, ' ')).join('\t') 771cb0ef41Sopenharmony_ci } 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci // stdout in tap is never a tty 801cb0ef41Sopenharmony_ci /* istanbul ignore next */ 811cb0ef41Sopenharmony_ci const maxWidth = process.stdout.isTTY ? process.stdout.getWindowSize()[0] : Infinity 821cb0ef41Sopenharmony_ci let output = columnify( 831cb0ef41Sopenharmony_ci [pkg], 841cb0ef41Sopenharmony_ci { 851cb0ef41Sopenharmony_ci include: columns, 861cb0ef41Sopenharmony_ci showHeaders: ++this.#line <= 1, 871cb0ef41Sopenharmony_ci columnSplitter: ' | ', 881cb0ef41Sopenharmony_ci truncate: !this.#opts.long, 891cb0ef41Sopenharmony_ci config: { 901cb0ef41Sopenharmony_ci name: { minWidth: 25, maxWidth: 25, truncate: false, truncateMarker: '' }, 911cb0ef41Sopenharmony_ci description: { minWidth: 20, maxWidth: 20 }, 921cb0ef41Sopenharmony_ci author: { minWidth: 15, maxWidth: 15 }, 931cb0ef41Sopenharmony_ci date: { maxWidth: 11 }, 941cb0ef41Sopenharmony_ci version: { minWidth: 8, maxWidth: 8 }, 951cb0ef41Sopenharmony_ci keywords: { maxWidth: Infinity }, 961cb0ef41Sopenharmony_ci }, 971cb0ef41Sopenharmony_ci } 981cb0ef41Sopenharmony_ci ).split('\n').map(line => line.slice(0, maxWidth)).join('\n') 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci if (!this.#opts.color) { 1011cb0ef41Sopenharmony_ci return output 1021cb0ef41Sopenharmony_ci } 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci const colors = ['31m', '33m', '32m', '36m', '34m', '35m'] 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci this.#opts.args.forEach((arg, i) => { 1071cb0ef41Sopenharmony_ci const markStart = String.fromCharCode(i % colors.length + 1) 1081cb0ef41Sopenharmony_ci const markEnd = String.fromCharCode(0) 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci if (arg.charAt(0) === '/') { 1111cb0ef41Sopenharmony_ci output = output.replace( 1121cb0ef41Sopenharmony_ci new RegExp(arg.slice(1, -1), 'gi'), 1131cb0ef41Sopenharmony_ci bit => `${markStart}${bit}${markEnd}` 1141cb0ef41Sopenharmony_ci ) 1151cb0ef41Sopenharmony_ci } else { 1161cb0ef41Sopenharmony_ci // just a normal string, do the split/map thing 1171cb0ef41Sopenharmony_ci let p = 0 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci output = output.toLowerCase().split(arg.toLowerCase()).map(piece => { 1201cb0ef41Sopenharmony_ci piece = output.slice(p, p + piece.length) 1211cb0ef41Sopenharmony_ci p += piece.length 1221cb0ef41Sopenharmony_ci const mark = `${markStart}${output.slice(p, p + arg.length)}${markEnd}` 1231cb0ef41Sopenharmony_ci p += arg.length 1241cb0ef41Sopenharmony_ci return `${piece}${mark}` 1251cb0ef41Sopenharmony_ci }).join('') 1261cb0ef41Sopenharmony_ci } 1271cb0ef41Sopenharmony_ci }) 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_ci for (let i = 1; i <= colors.length; i++) { 1301cb0ef41Sopenharmony_ci output = output.split(String.fromCharCode(i)).join(`\u001B[${colors[i - 1]}`) 1311cb0ef41Sopenharmony_ci } 1321cb0ef41Sopenharmony_ci return output.split('\u0000').join('\u001B[0m').trim() 1331cb0ef41Sopenharmony_ci } 1341cb0ef41Sopenharmony_ci} 135