????
Your IP : 3.143.212.252
const { stripVTControlCharacters } = require('node:util')
const { Minipass } = require('minipass')
const columnify = require('columnify')
// 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.
module.exports = async (opts) => {
return opts.json ? new JSONOutputStream() : new TextOutputStream(opts)
}
class JSONOutputStream extends Minipass {
#didFirst = false
write (obj) {
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 {
#opts
#line = 0
constructor (opts) {
super()
this.#opts = opts
}
write (pkg) {
return super.write(this.#prettify(pkg))
}
#prettify (data) {
const pkg = {
author: data.maintainers.map((m) => `=${stripVTControlCharacters(m.username)}`).join(' '),
date: 'prehistoric',
description: stripVTControlCharacters(data.description ?? ''),
keywords: '',
name: stripVTControlCharacters(data.name),
version: data.version,
}
if (Array.isArray(data.keywords)) {
pkg.keywords = data.keywords.map((k) => stripVTControlCharacters(k)).join(' ')
} else if (typeof data.keywords === 'string') {
pkg.keywords = stripVTControlCharacters(data.keywords.replace(/[,\s]+/, ' '))
}
if (data.date) {
pkg.date = data.date.toISOString().split('T')[0] // remove time
}
const columns = ['name', 'description', 'author', 'date', 'version', 'keywords']
if (this.#opts.parseable) {
return columns.map((col) => pkg[col] && ('' + pkg[col]).replace(/\t/g, ' ')).join('\t')
}
// stdout in tap is never a tty
/* istanbul ignore next */
const maxWidth = process.stdout.isTTY ? process.stdout.getWindowSize()[0] : Infinity
let output = columnify(
[pkg],
{
include: columns,
showHeaders: ++this.#line <= 1,
columnSplitter: ' | ',
truncate: !this.#opts.long,
config: {
name: { minWidth: 25, maxWidth: 25, truncate: false, truncateMarker: '' },
description: { minWidth: 20, maxWidth: 20 },
author: { minWidth: 15, maxWidth: 15 },
date: { maxWidth: 11 },
version: { minWidth: 8, maxWidth: 8 },
keywords: { maxWidth: Infinity },
},
}
).split('\n').map(line => line.slice(0, maxWidth)).join('\n')
if (!this.#opts.color) {
return output
}
const colors = ['31m', '33m', '32m', '36m', '34m', '35m']
this.#opts.args.forEach((arg, i) => {
const markStart = String.fromCharCode(i % colors.length + 1)
const markEnd = String.fromCharCode(0)
if (arg.charAt(0) === '/') {
output = output.replace(
new RegExp(arg.slice(1, -1), 'gi'),
bit => `${markStart}${bit}${markEnd}`
)
} else {
// just a normal string, do the split/map thing
let p = 0
output = output.toLowerCase().split(arg.toLowerCase()).map(piece => {
piece = output.slice(p, p + piece.length)
p += piece.length
const mark = `${markStart}${output.slice(p, p + arg.length)}${markEnd}`
p += arg.length
return `${piece}${mark}`
}).join('')
}
})
for (let i = 1; i <= colors.length; i++) {
output = output.split(String.fromCharCode(i)).join(`\u001B[${colors[i - 1]}`)
}
return output.split('\u0000').join('\u001B[0m').trim()
}
}