GIF89a=( õ' 7IAXKgNgYvYx\%wh…hŽth%ˆs%—x¨}9®Œ©€&©‰%¶†(¹–.¹5·œD¹&Çš)ÇŸ5ǘ;Í£*È¡&Õ²)ׯ7×µ<Ñ»4ï°3ø‘HÖ§KͯT÷¨Yÿšqÿ»qÿÔFØ !ù ' !ÿ NETSCAPE2.0 , =( þÀ“pH,È¤rÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßð¸|N¯Ûïø¼~Ïïûÿ€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§gª«ªE¯°¨¬ª±²Œ¹º¹E¾­”´ÂB¶¯ §Åȸ»ÑD¾¿Á•ÄÅ®° ÝH¾ÒLÀÆDÙ«D¶BÝïðÀ¾DÑÑÔTÌÍíH òGö¨A RÎڐ |¥ ٭&ºìE8œ¹kGÔAÞpx­a¶­ã R2XB®åE8I€Õ6Xî:vT)äžþÀq¦è³¥ì仕F~%xñ  4#ZÔ‰O|-4Bs‘X:= QÉ œš lºÒyXJŠGȦ|s hÏíK–3l7·B|¥$'7Jީܪ‰‡àá”Dæn=Pƒ ¤Òëí‰`䌨ljóá¯Éüv>á–Á¼5 ½.69ûϸd«­ºÀûnlv©‹ªîf{¬ÜãPbŸ  l5‘ޝpß ´ ˜3aÅùäI«O’ý·‘áÞ‡˜¾Æ‚ÙÏiÇÿ‹Àƒ #öó)pâš Þ½ ‘Ý{ó)vmÞü%D~ 6f s}ŃƒDØW Eþ`‡þ À…L8xá†ç˜{)x`X/> Ì}mø‚–RØ‘*|`D=‚Ø_ ^ð5 !_…'aä“OÚ—7âcð`D”Cx`ÝÂ¥ä‹éY¹—F¼¤¥Š?¡Õ™ n@`} lď’ÄÉ@4>ñd œ à‘vÒxNÃ×™@žd=ˆgsžG±æ ´²æud &p8Qñ)ˆ«lXD©øÜéAžHìySun jª×k*D¤LH] †¦§C™Jä–´Xb~ʪwStŽ6K,°£qÁœ:9ت:¨þªl¨@¡`‚ûÚ ».Û¬¯t‹ÆSÉ[:°=Š‹„‘Nåû”Ìî{¿ÂA ‡Rà›ÀÙ6úë°Ÿð0Ä_ ½;ÃϱîÉì^ÇÛÇ#Ëë¼ôº!±Ä˜íUîÅÇ;0L1óÁµö«p% AÀºU̬ݵ¼á%霼€‡¯Á~`ÏG¯»À× ­²± =4ªnpð3¾¤³¯­ü¾¦îuÙuµÙ®|%2ÊIÿür¦#0·ÔJ``8È@S@5ê¢ ö×Þ^`8EÜ]ý.뜃Âç 7 ú ȉÞj œ½Dç zý¸iþœÑÙûÄë!ˆÞÀl§Ïw‹*DçI€nEX¯¬¼ &A¬Go¼QföõFç°¯;é¦÷îŽêJ°îúôF5¡ÌQ|îúöXªæ»TÁÏyñêï]ê² o óÎC=öõ›ÒÓPB@ D×½œä(>èCÂxŽ`±«Ÿ–JЀ»Û á¤±p+eE0`ëŽ`A Ú/NE€Ø†À9‚@¤à H½7”à‡%B‰`Àl*ƒó‘–‡8 2ñ%¸ —€:Ù1Á‰E¸àux%nP1ð!‘ðC)¾P81lÑɸF#ˆ€{´âé°ÈB„0>±û °b¡Š´±O‚3È–Ù()yRpbµ¨E.Z‘D8ÊH@% òŒx+%Ù˜Æcü »¸˜fõ¬b·d`Fê™8èXH"ÉÈ-±|1Ô6iI, 2““¬$+](A*jÐ QTÂo‰.ÛU슬Œã„Ž`¯SN¡–¶Äåyše¯ª’­¬‚´b¦Éož œ)åyâ@Ì®3 ÎtT̉°&Ø+žLÀf"Ø-|žçÔ>‡Ðv¦Ðžì\‚ Q1)Ž@Žh#aP72”ˆ™¨$‚ !ù " , =( …7IAXG]KgNgYvYxR"k\%w]'}hŽth%ˆg+ˆs%—r.—m3šx3˜x¨}9®€&©€+¨‡7§‰%¶†(¹–.¹œD¹&ǘ;Í•&ײ)×»4ïÌ6ò§KÍ þ@‘pH,È¤rÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßð¸|N¯Ûïø¼~Ïïûÿ€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§g «¬ E ±± ¨­¶°ººE Á´”·®C¬²§Ç¶Œ»ÓDÃÕƷ¯Ê±H½ºM×ÁGÚ¬D¶BËÁ½î½DÓôTÏÛßîG»ôõC×CÌ l&âž:'òtU³6ɹ#·Ø)€'Ü.6±&ëÍÈ» K(8p0N?!æ2"ÛˆNIJX>R¼ÐO‚M '¡¨2¸*Ÿþ>#n↠å@‚<[:¡Iïf’ ¤TÚ˘CdbÜÙ“[«ŽEú5MBo¤×@€`@„€Êt W-3 ¶Ÿ¡BíêäjIÝ…Eò9[T…$íêﯧ„…•s»Óȳ¹€ÅÚdc®UUρ#±Ùïldj?´í¼²`\ŽÁðÞu|3'ÖŒ]ë6 ¶S#²‡˜FKLÈ *N E´‘áäŠ$˜›eÄYD„ºq«.è촁ƒs \-ÔjA 9²õ÷å- üúM[Âx(ís÷ì®x€|í¡Ù’p¦‚ ŽkÛTÇDpE@WÜ ²Ç]kŠ1¨ þ€·Yb ÓÁ‰l°*n0 ç™—žzBdОu¾7ĉBl€â‰-ºx~|UåU‰  h*Hœ|e"#"?vpÄiŠe6^ˆ„+qâŠm8 #VÇá ‘å–ÄV„œ|Аè•m"сœn|@›U¶ÆÎž—Špb¥G¨ED”€±Úê2FÌIç? >Éxå Œ± ¡¤„%‘žjŸ‘ꄯ<Ìaà9ijÐ2˜D¦È&›†Z`‚å]wþ¼Â:ç6àB¤7eFJ|õÒ§Õ,¨äàFÇ®cS·Ê¶+B°,‘Þ˜ºNûãØ>PADÌHD¹æž«ÄÀnÌ¥}­#Ë’ë QÀÉSÌÂÇ2ÌXÀ{æk²lQÁ2«ÊðÀ¯w|2Í h‹ÄÂG€,m¾¶ë3ÐÙ6-´ÅE¬L°ÆIij*K½ÀÇqï`DwVÍQXœÚÔpeœ±¬Ñ q˜§Tœ½µƒ°Œìu Â<¶aØ*At¯lmEØ ü ôÛN[P1ÔÛ¦­±$ÜÆ@`ùåDpy¶yXvCAyåB`ŽD¶ 0QwG#¯ æš[^Äþ $ÀÓÝǦ{„L™[±úKÄgÌ;ï£S~¹ìGX.ôgoT.»åˆ°ùŸûù¡?1zö¦Ÿž:ÅgÁ|ìL¹ „®£œŠ‚à0œ]PÁ^p F<"•ç?!,ñ‡N4—…PÄ Á„ö¨Û:Tè@hÀ‹%táÿ:ø-žI<`þ‹p I….)^ 40D#p@ƒj4–؀:²‰1Øâr˜¼F2oW¼#Z†;$Q q” ‘ ÂK¦ñNl#29 !’F@¥Bh·ᏀL!—XFóLH‘Kh¤.«hE&JòG¨¥<™WN!€ÑÙÚˆY„@†>Œž19J" 2,/ &.GXB%ÌRÈ9B6¹W]’î×ÔW¥’IÎ$ ñ‹ÓŒE8YÆ ¼³™ñA5“à®Q.aŸB€&Ø©³ JÁ—! ¦t)K%tœ-¦JF bòNMxLôþ)ÐR¸Ð™‘ èÝ6‘O!THÌ„HÛ ‰ !ù ) , =( …AXKgNgYvYxR"k\%wh…hŽh%ˆg+ˆs%—r.—x3˜x¨}9®€&©€+¨Œ,©‡7§‰%¶†(¹–.¹5·&Çš)ǘ;Í•&×£*Ȳ)ׯ7×»4ï°3øÌ6ò‘HÖ§KÍ»Hó¯T÷¨Yÿ»qÿÇhÿ þÀ”pH,È¤rÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßð¸|N¯Ûïø¼~Ïïûÿ€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§g ª« E$±²¨ª­ · °²½$E$ÂÕ««D· Í ¿¦Ç¶¸ÌŒ¾³CÃÅÆ E ééH½MÛÂGâªD­ çBêêϾD²ÒaÀà€Š1r­ðÓ¤ ÔožzU!L˜C'¾yW½UGtäÇïÙllê0×àÂuGþ)AÀs[þ·xì ÁxO%ƒûX2ó—  P£n›R/¡ÑšHše+êDm?# —‘Ç£6¡8íJ¡ŸâDiäªM¥Ö„ôj“¬¹£5oQ7°- <‡ *´lãÓŒ2r/a!l)dÈ A™ÈE¢ôÔ͆…ð ;Ö˜c ¡%ß‚’Ùˆâ¸b½—pe~C"BíëÚHïeF2§æŠ8qb t_`urŠeü wÅu3êæPv§h•"ß`íÍxçLĹÜÖ3á  ~Öº“®›¸ÏMDfJÙ °„ÛµáWõ%§œ‚à©–‚X ÓØ)@®Ñ›Eþ´wëuÅSxb8y\mÖzœ¥§ZbºE—ÂLªÌw!y(>¡™wú=Ç|ÅÝs¢d €CÁW)HÜcC$€L Ä7„r.á\{)@ð` @ äXÈ$PD” `šaG:§æˆOˆ72EÐamn]ù"ŒcÊxÑŒ° &dR8`g«iÙŸLR!¦P …d’ä¡“¦ðÎTƒ¦ià|À _ ¥ Qi#¦Šg›Æ ›noMµ ›V ã£)p ç£ÎW…š=Âeªk§†j„ ´®1ß²sÉxéW«jšl|0¯B0Û, \jÛ´›6±¬¶C ÛíWþï|ëÙ‹¸ñzĸV {ì;Ýñn¼òVˆm³I¼³.Ðã¤PN¥ ²µ¼„µCã+¹ÍByî£Ñ¾HŸ›ëê 7ìYÆFTk¨SaoaY$Dµœìï¿Ã29RÈkt Çïfñ ÇÒ:ÀÐSp¹3ÇI¨â¥DZÄ ü9Ïýögñ½­uÔ*3)O‘˜Ö[_hv ,àî×Et Ÿé¶BH€ Õ[ü±64M@ÔSÌM7dÐl5-ÄÙU܍´©zߌ3Ô€3ž„ „ ¶ÛPô½5×g› êÚ˜kN„Ý…0Îj4€Ìë°“#{þÕ3S2çKÜ'ợlø¼Ú2K{° {Û¶?žm𸧠ËI¼nEò='êüóºè^üæÃ_Û=°óž‚ì#Oý¿Í'¡½áo..ÏYìnüñCœO±Áa¿¢Kô½o,üÄËbö²çºíï{ËC Ú— "”Ï{ËK ÍÒw„õ±Oz dÕ¨à:$ ƒô—«v»] A#ð «€¿šéz)Rx׿ˆ¥‚d``èw-îyÏf×K!ð€þ­Ð|ìPľ„=Ì`ý(f” 'Pa ¥ÐBJa%Ðâf§„%Š¡}FàáÝ×6>ÉäŠG"éŽè=ø!oа^FP¼Ø©Q„ÀCÙÁ`(Ž\ÄÝ® ©Â$<n@dÄ E#ììUÒI! ‚#lù‹`k¦ÐÇ'Rró’ZýNBÈMF Í[¤+‹ðɈ-áwj¨¥þ8¾rá ,VÂh„"|½œ=×G_¦Ñ™EØ 0i*%̲˜Æda0mV‚k¾)›;„&6 p>ÓjK “¦Ç# âDÂ:ûc?:R Ó¬fÞéI-Ì“•Ã<ä=™Ï7˜3œ¨˜c2ŒW ,ˆ”8(T™P‰F¡Jhç"‚ ; 403WebShell
403Webshell
Server IP : 104.21.83.152  /  Your IP : 216.73.216.66
Web Server : LiteSpeed
System : Linux premium229.web-hosting.com 4.18.0-553.45.1.lve.el8.x86_64 #1 SMP Wed Mar 26 12:08:09 UTC 2025 x86_64
User : akhalid ( 749)
PHP Version : 8.3.22
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /opt/alt/alt-nodejs22/root/usr/lib/node_modules/npm/lib/commands/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /opt/alt/alt-nodejs22/root/usr/lib/node_modules/npm/lib/commands/view.js
const columns = require('cli-columns')
const { readFile } = require('node:fs/promises')
const jsonParse = require('json-parse-even-better-errors')
const { log, output, META } = require('proc-log')
const npa = require('npm-package-arg')
const { resolve } = require('node:path')
const formatBytes = require('../utils/format-bytes.js')
const relativeDate = require('tiny-relative-date')
const semver = require('semver')
const { inspect } = require('node:util')
const { packument } = require('pacote')
const Queryable = require('../utils/queryable.js')
const BaseCommand = require('../base-cmd.js')
const { getError } = require('../utils/error-message.js')
const { jsonError, outputError } = require('../utils/output-error.js')

const readJson = file => readFile(file, 'utf8').then(jsonParse)

class View extends BaseCommand {
  static description = 'View registry info'
  static name = 'view'
  static params = [
    'json',
    'workspace',
    'workspaces',
    'include-workspace-root',
  ]

  static workspaces = true
  static ignoreImplicitWorkspace = false
  static usage = ['[<package-spec>] [<field>[.subfield]...]']

  static async completion (opts, npm) {
    if (opts.conf.argv.remain.length <= 2) {
      // There used to be registry completion here, but it stopped
      // making sense somewhere around 50,000 packages on the registry
      return
    }
    // have the package, get the fields
    const config = {
      ...npm.flatOptions,
      fullMetadata: true,
      preferOnline: true,
    }
    const spec = npa(opts.conf.argv.remain[2])
    const pckmnt = await packument(spec, config)
    const defaultTag = npm.config.get('tag')
    const dv = pckmnt.versions[pckmnt['dist-tags'][defaultTag]]
    pckmnt.versions = Object.keys(pckmnt.versions).sort(semver.compareLoose)

    return getCompletionFields(pckmnt).concat(getCompletionFields(dv))
  }

  async exec (args) {
    let { pkg, local, rest } = parseArgs(args)

    if (local) {
      if (this.npm.global) {
        throw new Error('Cannot use view command in global mode.')
      }
      const dir = this.npm.prefix
      const manifest = await readJson(resolve(dir, 'package.json'))
      if (!manifest.name) {
        throw new Error('Invalid package.json, no "name" field')
      }
      // put the version back if it existed
      pkg = `${manifest.name}${pkg.slice(1)}`
    }

    await this.#viewPackage(pkg, rest)
  }

  async execWorkspaces (args) {
    const { pkg, local, rest } = parseArgs(args)

    if (!local) {
      log.warn('Ignoring workspaces for specified package(s)')
      return this.exec([pkg, ...rest])
    }

    const json = this.npm.config.get('json')
    await this.setWorkspaces()

    for (const name of this.workspaceNames) {
      try {
        await this.#viewPackage(`${name}${pkg.slice(1)}`, rest, { workspace: true })
      } catch (e) {
        const err = getError(e, { npm: this.npm, command: this })
        if (err.code !== 'E404') {
          throw e
        }
        if (json) {
          output.buffer({ [META]: true, jsonError: { [name]: jsonError(err, this.npm) } })
        } else {
          outputError(err)
        }
        process.exitCode = err.exitCode
      }
    }
  }

  async #viewPackage (name, args, { workspace } = {}) {
    const wholePackument = !args.length
    const json = this.npm.config.get('json')

    // If we are viewing many packages and outputting individual fields then
    // output the name before doing any async activity
    if (!json && !wholePackument && workspace) {
      output.standard(`${name}:`)
    }

    const [pckmnt, data] = await this.#getData(name, args, wholePackument)

    if (!json && wholePackument) {
      // pretty view (entire packument)
      for (const v of data) {
        output.standard(this.#prettyView(pckmnt, Object.values(v)[0][Queryable.ALL]))
      }
      return
    }

    const res = this.#packageOutput(cleanData(data, wholePackument), pckmnt._id)
    if (res) {
      if (json) {
        output.buffer(workspace ? { [name]: res } : res)
      } else {
        output.standard(res)
      }
    }
  }

  async #getData (pkg, args) {
    const spec = npa(pkg)

    const pckmnt = await packument(spec, {
      ...this.npm.flatOptions,
      preferOnline: true,
      fullMetadata: true,
    })

    // get the data about this package
    let version = this.npm.config.get('tag')
    // rawSpec is the git url if this is from git
    if (spec.type !== 'git' && spec.type !== 'directory' && spec.rawSpec !== '*') {
      version = spec.rawSpec
    }

    if (pckmnt['dist-tags']?.[version]) {
      version = pckmnt['dist-tags'][version]
    }

    if (pckmnt.time?.unpublished) {
      const u = pckmnt.time.unpublished
      throw Object.assign(new Error(`Unpublished on ${u.time}`), {
        statusCode: 404,
        code: 'E404',
        pkgid: pckmnt._id,
      })
    }

    const versions = pckmnt.versions || {}
    pckmnt.versions = Object.keys(versions).filter(v => {
      if (semver.valid(v)) {
        return true
      }
      log.info('view', `Ignoring invalid version: ${v}`)
      return false
    }).sort(semver.compareLoose)

    // remove readme unless we asked for it
    if (args.indexOf('readme') === -1) {
      delete pckmnt.readme
    }

    const data = Object.entries(versions)
      .filter(([v]) => semver.satisfies(v, version, true))
      .flatMap(([, v]) => {
        // remove readme unless we asked for it
        if (args.indexOf('readme') !== -1) {
          delete v.readme
        }
        return showFields({
          data: pckmnt,
          version: v,
          fields: args,
          json: this.npm.config.get('json'),
        })
      })

    // No data has been pushed because no data is matching the specified version
    if (!data.length && version !== 'latest') {
      throw Object.assign(new Error(`No match found for version ${version}`), {
        statusCode: 404,
        code: 'E404',
        pkgid: `${pckmnt._id}@${version}`,
      })
    }

    return [pckmnt, data]
  }

  #packageOutput (data, name) {
    const json = this.npm.config.get('json')
    const versions = Object.keys(data)
    const includeVersions = versions.length > 1

    let includeFields
    const res = versions.flatMap((v) => {
      const fields = Object.entries(data[v])

      includeFields ||= (fields.length > 1)

      const msg = json ? {} : []

      for (let [f, d] of fields) {
        d = cleanup(d)

        if (json) {
          msg[f] = d
          continue
        }

        if (includeVersions || includeFields || typeof d !== 'string') {
          d = inspect(d, {
            showHidden: false,
            depth: 5,
            colors: this.npm.color,
            maxArrayLength: null,
          })
        }

        if (f && includeFields) {
          f += ' = '
        }

        msg.push(`${includeVersions ? `${name}@${v} ` : ''}${includeFields ? f : ''}${d}`)
      }

      return msg
    })

    if (json) {
      // TODO(BREAKING_CHANGE): all unwrapping should be removed. Users should know
      // based on their arguments if they can expect an array or an object. And this
      // unwrapping can break that assumption. Eg `npm view abbrev@^2` should always
      // return an array, but currently since there is only one version matching `^2`
      // this will return a single object instead.
      const first = Object.keys(res[0] || {})
      const jsonRes = first.length === 1 ? res.map(m => m[first[0]]) : res
      if (jsonRes.length === 0) {
        return
      }
      if (jsonRes.length === 1) {
        return jsonRes[0]
      }
      return jsonRes
    }

    return res.join('\n').trim()
  }

  #prettyView (packu, manifest) {
    // More modern, pretty printing of default view
    const unicode = this.npm.config.get('unicode')
    const chalk = this.npm.chalk
    const deps = Object.entries(manifest.dependencies || {}).map(([k, dep]) =>
      `${chalk.blue(k)}: ${dep}`
    )
    const site = manifest.homepage?.url || manifest.homepage
    const bins = Object.keys(manifest.bin || {})
    const licenseField = manifest.license || 'Proprietary'
    const license = typeof licenseField === 'string'
      ? licenseField
      : (licenseField.type || 'Proprietary')

    const res = []

    res.push('')
    res.push([
      chalk.underline.cyan(`${manifest.name}@${manifest.version}`),
      license.toLowerCase().trim() === 'proprietary'
        ? chalk.red(license)
        : chalk.green(license),
      `deps: ${deps.length ? chalk.cyan(deps.length) : chalk.cyan('none')}`,
      `versions: ${chalk.cyan(packu.versions.length + '')}`,
    ].join(' | '))

    manifest.description && res.push(manifest.description)
    if (site) {
      res.push(chalk.blue(site))
    }

    manifest.deprecated && res.push(
      `\n${chalk.redBright('DEPRECATED')}${unicode ? ' ⚠️ ' : '!!'} - ${manifest.deprecated}`
    )

    if (packu.keywords?.length) {
      res.push(`\nkeywords: ${
        packu.keywords.map(k => chalk.cyan(k)).join(', ')
      }`)
    }

    if (bins.length) {
      res.push(`\nbin: ${chalk.cyan(bins.join(', '))}`)
    }

    res.push('\ndist')
    res.push(`.tarball: ${chalk.blue(manifest.dist.tarball)}`)
    res.push(`.shasum: ${chalk.green(manifest.dist.shasum)}`)
    if (manifest.dist.integrity) {
      res.push(`.integrity: ${chalk.green(manifest.dist.integrity)}`)
    }
    if (manifest.dist.unpackedSize) {
      res.push(`.unpackedSize: ${chalk.blue(formatBytes(manifest.dist.unpackedSize, true))}`)
    }

    if (deps.length) {
      const maxDeps = 24
      res.push('\ndependencies:')
      res.push(columns(deps.slice(0, maxDeps), { padding: 1 }))
      if (deps.length > maxDeps) {
        res.push(chalk.dim(`(...and ${deps.length - maxDeps} more.)`))
      }
    }

    if (packu.maintainers?.length) {
      res.push('\nmaintainers:')
      packu.maintainers.forEach(u =>
        res.push(`- ${unparsePerson({
          name: chalk.blue(u.name),
          email: chalk.dim(u.email) })}`)
      )
    }

    res.push('\ndist-tags:')
    res.push(columns(Object.entries(packu['dist-tags']).map(([k, t]) =>
      `${chalk.blue(k)}: ${t}`
    )))

    const publisher = manifest._npmUser && unparsePerson({
      name: chalk.blue(manifest._npmUser.name),
      email: chalk.dim(manifest._npmUser.email),
    })
    if (publisher || packu.time) {
      let publishInfo = 'published'
      if (packu.time) {
        publishInfo += ` ${chalk.cyan(relativeDate(packu.time[manifest.version]))}`
      }
      if (publisher) {
        publishInfo += ` by ${publisher}`
      }
      res.push('')
      res.push(publishInfo)
    }

    return res.join('\n')
  }
}

module.exports = View

function parseArgs (args) {
  if (!args.length) {
    args = ['.']
  }

  const pkg = args.shift()

  return {
    pkg,
    local: /^\.@/.test(pkg) || pkg === '.',
    rest: args,
  }
}

function cleanData (obj, wholePackument) {
  // JSON formatted output (JSON or specific attributes from packument)
  const data = obj.reduce((acc, cur) => {
    if (cur) {
      Object.entries(cur).forEach(([k, v]) => {
        acc[k] ||= {}
        Object.keys(v).forEach((t) => {
          acc[k][t] = cur[k][t]
        })
      })
    }
    return acc
  }, {})

  if (wholePackument) {
    const cleaned = Object.entries(data).reduce((acc, [k, v]) => {
      acc[k] = v[Queryable.ALL]
      return acc
    }, {})
    log.silly('view', cleaned)
    return cleaned
  }

  return data
}

// return whatever was printed
function showFields ({ data, version, fields, json }) {
  const o = [data, version].reduce((acc, s) => {
    Object.entries(s).forEach(([k, v]) => {
      acc[k] = v
    })
    return acc
  }, {})

  const queryable = new Queryable(o)

  if (!fields.length) {
    return { [version.version]: queryable.query(Queryable.ALL) }
  }

  return fields.map((field) => {
    const s = queryable.query(field, { unwrapSingleItemArrays: !json })
    if (s) {
      return { [version.version]: s }
    }
  })
}

function cleanup (data) {
  if (Array.isArray(data)) {
    return data.map(cleanup)
  }

  if (!data || typeof data !== 'object') {
    return data
  }

  const keys = Object.keys(data)
  if (keys.length <= 3 && data.name && (
    (keys.length === 1) ||
    (keys.length === 3 && data.email && data.url) ||
    (keys.length === 2 && (data.email || data.url))
  )) {
    data = unparsePerson(data)
  }

  return data
}

const unparsePerson = (d) =>
  `${d.name}${d.email ? ` <${d.email}>` : ''}${d.url ? ` (${d.url})` : ''}`

function getCompletionFields (d, f = [], pref = []) {
  Object.entries(d).forEach(([k, v]) => {
    if (k.charAt(0) === '_' || k.indexOf('.') !== -1) {
      return
    }
    const p = pref.concat(k).join('.')
    f.push(p)
    if (Array.isArray(v)) {
      v.forEach((val, i) => {
        const pi = p + '[' + i + ']'
        if (val && typeof val === 'object') {
          getCompletionFields(val, f, [p])
        } else {
          f.push(pi)
        }
      })
      return
    }
    if (typeof v === 'object') {
      getCompletionFields(v, f, [p])
    }
  })
  return f
}

Youez - 2016 - github.com/yon3zu
LinuXploit