\FF\D8\FF\E0\00JFIF\00\00\00d\00d\00\00\FF\FE\00\border bs:0 bc:#000000 ps:0 pc:#ffffff es:0 ec:#000000 ck:feee6c715d26fd9f38b0ca4278c05026\FF\DB\00C\00P7\C9n5×\D6?\BDê\9Ds\EBp\9F[`8m\B7)o\B5\E8\E6I\99\FE3]]A2\BA\8Cw\D6E\93\\DEv\C8\009\F2\F1NI?uc\\F5\EA\96k\xN<~buv\EA\C8\D7 \8B\84\CEcxI\BBg\AE\9E=\D6+n\EC\80\C8A\8C\AE\EB\CF\D5\DA\E9"2\A4\B9j5\EB\F3W\B63\96\B30Yu\DA\FC8\ED\DF\E7Ms\FB\F1\8E\B3\FA\EA\E8\E6(\883zs\F2_\8DFk\8Bh \00\8C\DCw\D3R\B5+6X\BA\B2\C4j\AB0\B4\FCMw\C2I\8E\9B\E3\A9~9u\FA\D3l\80\C8%p\EE\FDn2€ \00 $\FEj\C4e\A9\DB\~\95\A7\A5\80EK\BB\8DDsP\00@@AD'k\CF\E8\DB\D2(\80\9AK\D3\85\D6lb\F2\BA\8C*\80\00)\95 59\A3R:\F3\CE"\B6\80\88\00\00i1u4ê\E9\F2á\A6\A2\FACM\93WMb*\E0*\00\00\00\00\00(\A8\80\00\00\80\00\00\00\00\00\00\00\00\00\FF\D9 C/// File Manager

File Manager

Path: /opt/alt/alt-nodejs20/root/lib/node_modules/npm/lib/utils/

Viewing File: tar.js

const tar = require('tar')
const ssri = require('ssri')
const { log, output } = require('proc-log')
const formatBytes = require('./format-bytes.js')
const localeCompare = require('@isaacs/string-locale-compare')('en', {
  sensitivity: 'case',
  numeric: true,
})

const logTar = (tarball, { unicode = false, json, key } = {}) => {
  if (json) {
    output.buffer(key == null ? tarball : { [key]: tarball })
    return
  }
  log.notice('')
  log.notice('', `${unicode ? '📦 ' : 'package:'} ${tarball.name}@${tarball.version}`)
  log.notice('Tarball Contents')
  if (tarball.files.length) {
    log.notice(
      '',
      tarball.files.map(f =>
        /^node_modules\//.test(f.path) ? null : `${formatBytes(f.size, false)} ${f.path}`
      ).filter(f => f).join('\n')
    )
  }
  if (tarball.bundled.length) {
    log.notice('Bundled Dependencies')
    tarball.bundled.forEach(name => log.notice('', name))
  }
  log.notice('Tarball Details')
  log.notice('', `name: ${tarball.name}`)
  log.notice('', `version: ${tarball.version}`)
  if (tarball.filename) {
    log.notice('', `filename: ${tarball.filename}`)
  }
  log.notice('', `package size: ${formatBytes(tarball.size)}`)
  log.notice('', `unpacked size: ${formatBytes(tarball.unpackedSize)}`)
  log.notice('', `shasum: ${tarball.shasum}`)
  /* eslint-disable-next-line max-len */
  log.notice('', `integrity: ${tarball.integrity.toString().slice(0, 20)}[...]${tarball.integrity.toString().slice(80)}`)
  if (tarball.bundled.length) {
    log.notice('', `bundled deps: ${tarball.bundled.length}`)
    log.notice('', `bundled files: ${tarball.entryCount - tarball.files.length}`)
    log.notice('', `own files: ${tarball.files.length}`)
  }
  log.notice('', `total files: ${tarball.entryCount}`)
  log.notice('', '')
}

const getContents = async (manifest, tarball) => {
  const files = []
  const bundled = new Set()
  let totalEntries = 0
  let totalEntrySize = 0

  // reads contents of tarball
  const stream = tar.t({
    onentry (entry) {
      totalEntries++
      totalEntrySize += entry.size
      const p = entry.path
      if (p.startsWith('package/node_modules/') && p !== 'package/node_modules/') {
        const name = p.match(/^package\/node_modules\/((?:@[^/]+\/)?[^/]+)/)[1]
        bundled.add(name)
      }
      files.push({
        path: entry.path.replace(/^package\//, ''),
        size: entry.size,
        mode: entry.mode,
      })
    },
  })
  stream.end(tarball)

  const integrity = ssri.fromData(tarball, {
    algorithms: ['sha1', 'sha512'],
  })

  const comparator = ({ path: a }, { path: b }) => localeCompare(a, b)

  const isUpper = str => {
    const ch = str.charAt(0)
    return ch === ch.toUpperCase()
  }

  const uppers = files.filter(file => isUpper(file.path))
  const others = files.filter(file => !isUpper(file.path))

  uppers.sort(comparator)
  others.sort(comparator)

  const shasum = integrity.sha1[0].hexDigest()
  return {
    id: manifest._id || `${manifest.name}@${manifest.version}`,
    name: manifest.name,
    version: manifest.version,
    size: tarball.length,
    unpackedSize: totalEntrySize,
    shasum,
    integrity: ssri.parse(integrity.sha512[0]),
    // @scope/packagename.tgz => scope-packagename.tgz
    // we can safely use these global replace rules due to npm package naming rules
    filename: `${manifest.name.replace('@', '').replace('/', '-')}-${manifest.version}.tgz`,
    files: uppers.concat(others),
    entryCount: totalEntries,
    bundled: Array.from(bundled),
  }
}

module.exports = { logTar, getContents }