....................................../////.===Hehe-Here===./////................................................ > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < ------------------------------------------------------------------------------------------------------------------- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// RIFF¤ WEBPVP8 ˜ ðÑ *ôô>‘HŸK¥¤"§£±¨àð enü¹%½_F‘åè¿2ºQú³íªú`N¿­3ÿƒügµJžaÿ¯ÿ°~¼ÎùnúîÞÖô•òíôÁÉß®Sm¥Ü/ ‡ó˜f£Ùà<˜„xëJ¢Ù€SO3x<ªÔ©4¿+ç¶A`q@Ì“Úñè™ÍÿJÌ´ª-˜ÆtÊÛL]Ïq*‘Ý”ì#ŸÌÏãY]@ê`¿ /ªfkØB4·®£ó z—Üw¥Pxù–ÞLШKÇN¾AkÙTf½è'‰g gÆv›Øuh~ a˜Z— ïj*á¥t d£“uÒ ¨`K˜¹ßþ]b>˜]_ÏÔ6W—è2r4x•íÖ…"ƒÖNîä!¦å Ú}ýxGøÌ —@ ;ÆÚŠ=ɾ1ý8lªË¥ô ^yf®Œ¢u&2©nÙÇ›ñÂñŒ³ aPo['½»øFùà­+4ê“$!lövlüÞ=;N®3ð‚õ›DÉKòÞ>ÄÍ ¥ˆuߤ#ˆ$6ù™¥îЇy’ÍB¼ çxÛ;X"WL£R÷͝*ó-¶Zu}º.s¸sšXqù–DþÿvªhüïwyŸ ¯é³lÀ:KCûÄ£Ëá\…­ ~—ýóî ¼ûûÜTÓüÇy…ŽÆvc»¾×U ñ¸žþоP÷¦ó:Ò¨¨5;Ð#&#ÖúñläÿÁœ GxÉ­/ñ‡áQðìYÉtÒw޼GÔ´zàÒò ð*ëzƒ•4~H]Ø‹f ñÓÈñ`NåWçs'ÆÏW^ø¹!XžµmQ5ÃËoLœÎ: ÞËÍ¥J ù…î èo£ßPÎñ¶ž8.Œ]ʵ~5›ÙË-ù*8ÙÖß±~ ©¹rÓê‚j¶d¸{^Q'˜±Crß ÚH—#¥¥QlÀ×ëã‡DÜ«èî þ&Çæžî;ŽÏºò6ÒLÃXy&ZŒ'j‚¢Ù€IßÚù+–MGi‰*jE€‘JcÜ ÓÌ EÏÚj]o˜ Þr <¾U ûŪæÍ/šÝH¥˜b”¼ ÁñßX GP›ï2›4WŠÏà×£…íÓk†¦H·ÅíMh–*nó÷à]ÁjCº€b7<ب‹¨5車bp2:Á[UªM„QŒçiNMa#<5›áËó¸HýÊ"…×Éw¹¦ì2º–x<›»a±¸3Weü®FÝ⑱ö–î–³|LPÈ~çð~Çå‡|º kD¢µÏàÆAI %1À% ¹Ò – ”ϝS¦‰4&¶£°à Öý”û_Ò Áw°A«Å€?mÇÛgHÉ/8)á¾ÛìáöŽP í¨PŸNÙµº¦‡§Ùš"ÿ«>+ªÕ`Ê÷‡‚ß Õû˜þãÇ-PÍ.¾XV‘€ dÜ"þ4¹ ±Oú‘©t¥¦FªÄÃÄ•b‚znýu½—#cDs˜ÃiÑOˆñ×QO=*IAÊ,¶ŽZƒ;‡wøXè%EÐk:F±Ú” .Ѽ+Áu&Ç`."pÈÉw o&¿dE6‘’EqTuK@Ì¥ã™À(Êk(h‰,H}RÀIXÛš3µ1©_OqÚÒJAñ$ÊÙÜ;D3çŒ[þùœh¬Ã³™ö6ç†NY".Ú‰ï[ªŸŒ '²Ð öø_¨ÂÉ9ué¶³ÒŠõTàîMØ#û¯gN‡bÙ놚X„ö …ÉeüÌ^J ‹€.œ$Æ)βÄeæW#óüßĺŸ€ ÀzwV 9oä»f4V*uB «Ë†¹ì¯žR霓æHXa=&“I4K;¯ç‹h×·"UŠ~<•╪Vêª&ÍSÃÆÅ?ÔqÎ*mTM ˜›µwêd#[C¡©§‘D<©àb†–ÁœøvH/,í:¯( ²£|4-„Æövv„Yͼ™^Á$ˆ„¢Û[6yB.åH*V¨æ?$=˜Ñ€•ñ·­(VlŸ‘ nÀt8W÷´Bûba?q9ú¶Xƒl«ÿ\ù¶’þòUÐj/õ¢Ìµ³g$ƒÎR!¸»|Oߍë’BhîÚÑ¢ñåŒJ„®„£2Ð3•ô02Nt…!£Í]Ïc½Qÿ?ˆ<&ÃA¾Ú,JˆijÌ#5yz„‰Î|ÊŽ5QÏ:‹ÐaóVÔxW—CpeÏzÐïíçôÿÅ_[hãsÐ_/ŽTÝ?BîˆííV$<¿i>²F¬_Eß¿ †bÊŒº­ÿ®Z H“C}”¬,Mp ý/Bá£w>˜YV°aƒúh+cŠ- r/[%|üUMHäQ°X»|û/@|°¥Ð !BÔ Ç¢Ä©š+Õì D«7ìN¶ŽðÔ " ƶ’ÖçtA‰Û×}{tþz­¾GÍ›k¹OEJR$ Â׃ «ëÁ"oÉôž$oUK(Ä)Ãz³Ê-‹êN[Ò3Œñbï8P 4ƒ×q¢bo|?<ÛX¬òÄͰL–±›(™ûG?ýË©ÚÄ–ÂDØÐ_Ç¡ô ¾–ÄÏø ×e8Ë©$ÄF¹Å‹ì[©óìl:F¾f´‹‹Xì²ï®\¬ôùƒ ÿat¥óèÒùHß0äe‚;ü×h:ÆWðHž=Ã8骣"kœ'Y?³}Tûè€>?0l›e1Lòñ„aæKÆw…hÖŠùW…ÈÆÄ0ši·›[pcwËþñiêíY/~-Á5˜!¿†A›™Mÿþ(±“t@â“ö2­´TG5yé]çå僳 .·ÍïçÝ7UÚ±Ð/Nè»,_Ï ùdj7\ï Wì4›„»c¸àešg#ÒÊ⥭áØo5‘?ÌdÝô¯ ¹kzsƒ=´#ëÉK›Ø´±-¥eW?‡çßtòTã…$Ý+qÿ±ƒ÷_3Ô¥í÷:æ–ž<·Ö‡‰Å¢ š‡%Ô—utÌÈìðžgÖÀz²À—ï÷Óîäõ{K'´È÷³yaÏÁjƒô}ž§®æÊydÕÈë5¯èˆõvÕ©ã*çD„ “z„Ó‡^^xÂ3M§A´JG‚öï 3W'ˆ.OvXè¡ÊÕª?5º7†˜(˜Ç¶#çê’¶!ÌdZK§æ 0fãaN]òY³RV ™î$®K2R¨`W!1Ôó\;Ý ýB%qæK•&ÓÈe9È0êI±žeŸß -ú@žQr¦ ö4»M¼Áè¹µmw 9 EÆE_°2ó„ŸXKWÁ×Hóì^´²GѝF©óäR†¦‰ç"V»eØ<3ùd3ÿÚ¤Žú“Gi" —‘_ÙËÎ~Üö¯¥½Î»üŸEÚŽåmÞþí ;ÞólËΦMzA"Âf(´òá;Éï(/7½ûñÌ­cïÕçлþÝz¾-ÍvÑ“pH­–ðÓj$¸Äû¤‚‘ãUBË-n“2åPkS5&‹Â|+g^œ®Ì͆d!OïäîU«c;{Û!ÅŽ«ëZ9Ókóˆ]¯ƒ›né `ÇÒ+tÆš (ØKá¾—=3œ®•vuMñg²\ï Ec€ 05±d™‡×iÇ×›UúvÌ¢£Èþ¡ÕØô¶ßÎA"ß±#Ö²ˆÊŸ¦*Ä~ij|àø.-¼'»Ú¥£h ofº¦‡VsR=N½„Î v˜Z*SÌ{=jÑB‹tê…;’HžH¯8–îDù8ñ¢|Q•bÛçš–‹m³“ê¨ åÏ^m¬Žãþ©ïêO‡½6] µÆ„Ooòü ²x}N¦Ë3ïé¿»€›HA˜m%çÞ/¿í7Fø“‹léUk)É°Œµ8Q8›:ÀŠeT*šõ~ôڝG6 ¢}`ùH­–”¡k ‰P1>š†®9z11!X wKfmÁ¦xÑ,N1Q”–æB¶M…ÒÃv6SMˆhU¬ÊPŽï‘öj=·CŒ¯u¹ƒVIЃsx4’ömÛýcå¡¶7ßŠß 57^\wÒÐÆ k§h,Œý î«q^R½3]J¸ÇðN ‚çU¬ôº^Áì} ³f©Õœ§ˆã:FÄÈ‚é(€™?àýÓüè1Gô£¼éj‚OÅñ  #>×—ßtà 0G¥Åa뀐kßhc™À_ÉñÞ#±)GD" YîäË-ÿÙ̪ ¹™a¯´¢E\ÝÒö‚;™„ë]_ p8‰o¡ñ+^÷ 3‘'dT4œŽ ðVë½° :¬víÑ«£tßÚS-3¶“þ2 †üüʨòrš¹M{É_¤`Û¨0ìjœøJ‡:÷ÃáZ˜†@GP&œÑDGÏs¡þ¦þDGú‘1Yá9Ôþ¼ ûø…§÷8&–ÜÑnÄ_m®^üÆ`;ÉVÁJ£?â€-ßê}suÍ2sõA NÌúA磸‘îÿÚ»ƒìö·á¿±tÑÐ"Tÿü˜[@/äj¬€uüªìù¥Ý˜á8Ý´sõj 8@rˆð äþZÇD®ÿUÏ2ùôõrBzÆÏÞž>Ì™xœ“ wiÎ×7_… ¸ \#€MɁV¶¥üÕÿPÔ9Z‡ø§É8#H:ƒ5ÀÝå9ÍIŒ5åKÙŠ÷qÄ>1AÈøžj"µÂд/ªnÀ qªã}"iŸBå˜ÓÛŽ¦…&ݧ;G@—³b¯“•"´4í¨ôM¨åñC‹ïùÉó¯ÓsSH2Ý@ßáM‡ˆKÀªÛUeø/4\gnm¥‹ŸŒ qÄ b9ÞwÒNÏ_4Ég³ú=܆‚´ •â¥õeíþkjz>éÚyU«Íӝ݃6"8/ø{=Ô¢»G¥ äUw°W«,ô—¿ãㆅү¢³xŠUû™yŒ (øSópÐ 9\åTâ»—*oG$/×ÍT†Y¿1¤Þ¢_‡ ¼ „±ÍçèSaÓ 3ÛMÁBkxs‰’R/¡¤ˆÙçª(*õ„üXÌ´ƒ E§´¬EF"Ù”R/ÐNyÆÂ^°?™6¡œïJ·±$§?º>ÖüœcNÌù¯G ‹ñ2ЁBB„^·úìaz¨k:#¨Æ¨8LÎõލ£^§S&cŒÐU€ü(‡F±Š¼&P>8ÙÁ ‰ p5?0ÊÆƒZl¸aô š¼¡}gÿ¶zÆC²¹¬ÎÖG*HB¡O<º2#ñŒAƒ–¡B˜´É$¥›É:FÀÔx¾u?XÜÏÓvN©RS{2ʈãk9rmP¼Qq̳ è¼ÐFׄ^¡Öì fE“F4A…!ì/…¦Lƒ… … $%´¾yã@CI¬ á—3PþBÏNÿ<ý°4Ü ËÃ#ØÍ~âW«rEñw‹eùMMHß²`¬Öó½íf³:‹k˜¯÷}Z!ã¿<¥,\#öµÀ¯aÒNÆIé,Ћ–lŽ#Àæ9ÀÒS·I’½-Ïp Äz¤Š Â* ­íÄ9­< h>׍3ZkËU¹§˜ŒŠ±f­’¤º³Q ÏB?‹#µíÃ¥®@(Gs«†vI¥Mµ‹Á©e~2ú³ÁP4ìÕi‚²Ê^ö@-DþÓàlÜOÍ]n"µã:žpsŽ¢:! Aõ.ç~ÓBûH÷JCÌ]õVƒd «ú´QÙEA–¯¯Œ!.ˆˆëQ±ù œ·Ì!Õâ )ùL„ÅÀlÚè5@B…o´Æ¸XÓ&Û…O«˜”_#‡ƒ„ûÈt!¤ÁÏ›ÎÝŠ?c9 â\>lÓÁVÄÑ™£eØY]:fÝ–—ù+p{™ðè û³”g±OƒÚSù£áÁÊ„ä,ï7š²G ÕÌBk)~ÑiCµ|h#u¤¶îK¨² #²vݯGãeÖ϶ú…¾múÀ¶þÔñ‚Š9'^($¤§ò “š½{éúp÷J›ušS¹áªCÂubÃH9™D™/ZöØÁ‡¦ÝÙŸ·kð*_”.C‹{áXó€‡c¡c€§/šò/&éš÷,àéJþ‰X›fµ“C¨œ®r¬"kL‰Â_q…Z–.ÉL~O µ›zn‚¹À¦Öª7\àHµšÖ %»ÇníV[¥*Õ;ƒ#½¾HK-ÖIÊdÏEÚ#=o÷Óò³´Š: Ç?{¾+9›–‘OEáU·S€˜j"ÄaÜ ŒÛWt› á–c#a»pÔZÞdŽtWê=9éöÊ¢µ~ ë ;Öe‡Œ®:bî3±ýê¢wà¼îpêñ¹¾4 zc¾ðÖÿzdêŒÑÒŝÀ‰s6¤í³ÎÙB¿OZ”+F¤á‡3@Ñëäg©·Ž ˆèª<ù@É{&S„œÕúÀA)‰h:YÀ5^ÂÓŒ°õäU\ ùËÍû#²?Xe¬tu‰^zÒÔãë¼ÛWtEtû …‚g¶Úüâî*moGè¨7%u!]PhÏd™Ý%Îx: VÒ¦ôÊD3ÀŽKÛËãvÆî…N¯ä>Eró–ð`5 Œ%u5XkñÌ*NU%¶áœÊ:Qÿú»“úzyÏ6å-၇¾ ´ ÒÊ]y žO‘w2Äøæ…H’²f±ÎÇ.ª|¥'gîV•Ü .̘¯€šòü¤U~Ù†*¢!?ò wý,}´°ÔÞnïoKq5µb!áÓ3"vAßH¡³¡·G(ÐÎ0Îò¼MG!/ài®@—¬04*`…«é8ªøøló“ˆÊ”èù¤…ßÊoÿé'ËuÌÖ5×È¡§ˆˆfŽë9}hìâ_!!¯  B&Ëö¶‰ÀAÙNVŸ Wh›¸®XÑJì¨ú“¿÷3uj²˜¨ÍÎìë±aúŠÝå¯ð*Ó¨ôJ“yºØ)m°WýOè68†ŸÏ2—‰Ïüꪫٚ¥‹l1 ø ÏÄFjêµvÌbü¦èÝx:X±¢H=MÐß—,ˆÉÇ´(9ú¾^ÅÚ4¿m‡$âX‘å%(AlZo@½¨UOÌÕ”1ø¸jÎÀÃÃ_ µ‘Ü.œº¦Ut: Æï’!=¯uwû#,“pþÇúŒø(é@?³ü¥‘Mo §—s@Œ#)§ŒùkL}NOÆêA›¸~r½¼ÙA—HJ«eˆÖ´*¡ÓpÌŸö.m<-"³ûÈ$¬_6­åf£ïÚâj1y§ÕJ½@dÞÁr&Í\Z%D£Íñ·AZ Û³øüd/ªAi†/Й~  ‡âĮҮÏh§°b—›Û«mJžòG'[ÈYýŒ¦9psl ýÁ ®±f¦x,‰½tN ‚Xª9 ÙÖH.«Lo0×?͹m¡å†Ѽ+›2ƒF ±Ê8 7Hցϓ²Æ–m9…òŸï]Â1äN†VLâCˆU .ÿ‰Ts +ÅÎx(%¦u]6AF Š ØF鈄‘ |¢¶c±soŒ/t[a¾–û:s·`i햍ê›ËchÈ…8ßÀUÜewŒðNOƒõD%q#éû\9¤x¹&UE×G¥ Í—™$ð E6-‡¼!ýpãÔM˜ Âsìe¯ñµK¢Ç¡ùôléœ4Ö£”À Š®Ðc ^¨À}ÙËŸ§›ºê{ÊuÉC ×Sr€¤’fÉ*j!úÓ’Gsùìoîßîn%ò· àc Wp÷$¨˜)û»H ×8ŽÒ€Zj¤3ÀÙºY'Ql¦py{-6íÔCeiØp‘‡XÊîÆUߢ܂ž£Xé¼Y8þ©ëgñß}é.ÎógÒ„ÃØËø¯»™§Xýy M%@NŠ À(~áÐvu7&•,Ù˜ó€uP‡^^®=_E„jt’ 403WebShell
403Webshell
Server IP : 159.198.67.129  /  Your IP : 216.73.216.75
Web Server : LiteSpeed
System : Linux server166.web-hosting.com 4.18.0-513.18.1.lve.el8.x86_64 #1 SMP Thu Feb 22 12:55:50 UTC 2024 x86_64
User : trooaisr ( 4033)
PHP Version : 7.4.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /opt/alt/alt-nodejs20/root/lib/node_modules/npm/lib/utils/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /opt/alt/alt-nodejs20/root/lib/node_modules/npm/lib/utils/display.js
const { log, output, input, META } = require('proc-log')
const { explain } = require('./explain-eresolve.js')
const { formatWithOptions } = require('./format')

// This is the general approach to color:
// Eventually this will be exposed somewhere we can refer to these by name.
// Foreground colors only. Never set the background color.
/*
 * Black # (Don't use)
 * Red # Danger
 * Green # Success
 * Yellow # Warning
 * Blue # Accent
 * Magenta # Done
 * Cyan # Emphasis
 * White # (Don't use)
 */

// Translates log levels to chalk colors
const COLOR_PALETTE = ({ chalk: c }) => ({
  heading: c.bold,
  title: c.blueBright,
  timing: c.magentaBright,
  // loglevels
  error: c.red,
  warn: c.yellow,
  notice: c.cyanBright,
  http: c.green,
  info: c.cyan,
  verbose: c.blue,
  silly: c.blue.dim,
})

const LEVEL_OPTIONS = {
  silent: {
    index: 0,
  },
  error: {
    index: 1,
  },
  warn: {
    index: 2,
  },
  notice: {
    index: 3,
  },
  http: {
    index: 4,
  },
  info: {
    index: 5,
  },
  verbose: {
    index: 6,
  },
  silly: {
    index: 7,
  },
}

const LEVEL_METHODS = {
  ...LEVEL_OPTIONS,
  [log.KEYS.timing]: {
    show: ({ timing, index }) => !!timing && index !== 0,
  },
}

const setBlocking = (stream) => {
  // Copied from https://github.com/yargs/set-blocking
  // https://raw.githubusercontent.com/yargs/set-blocking/master/LICENSE.txt
  /* istanbul ignore next - we trust that this works */
  if (stream._handle && stream.isTTY && typeof stream._handle.setBlocking === 'function') {
    stream._handle.setBlocking(true)
  }
  return stream
}

// These are important
// This is the key that is returned to the user for errors
const ERROR_KEY = 'error'
// This is the key producers use to indicate that there
// is a json error that should be merged into the finished output
const JSON_ERROR_KEY = 'jsonError'

const isPlainObject = (v) => v && typeof v === 'object' && !Array.isArray(v)

const getArrayOrObject = (items) => {
  if (items.length) {
    const foundNonObject = items.find(o => !isPlainObject(o))
    // Non-objects and arrays cant be merged, so just return the first item
    if (foundNonObject) {
      return foundNonObject
    }
    // We use objects with 0,1,2,etc keys to merge array
    if (items.every((o, i) => Object.hasOwn(o, i))) {
      return Object.assign([], ...items)
    }
  }
  // Otherwise its an object with all object items merged together
  return Object.assign({}, ...items.filter(o => isPlainObject(o)))
}

const getJsonBuffer = ({ [JSON_ERROR_KEY]: metaError }, buffer) => {
  const items = []
  // meta also contains the meta object passed to flush
  const errors = metaError ? [metaError] : []
  // index 1 is the meta, 2 is the logged argument
  for (const [, { [JSON_ERROR_KEY]: error }, obj] of buffer) {
    if (obj) {
      items.push(obj)
    }
    if (error) {
      errors.push(error)
    }
  }

  if (!items.length && !errors.length) {
    return null
  }

  const res = getArrayOrObject(items)

  // This skips any error checking since we can only set an error property
  // on an object that can be stringified
  // XXX(BREAKING_CHANGE): remove this in favor of always returning an object with result and error keys
  if (isPlainObject(res) && errors.length) {
    // This is not ideal. JSON output has always been keyed at the root with an `error`
    // key, so we cant change that without it being a breaking change. At the same time
    // some commands output arbitrary keys at the top level of the output, such as package
    // names. So the output could already have the same key. The choice here is to overwrite
    // it with our error since that is (probably?) more important.
    // XXX(BREAKING_CHANGE): all json output should be keyed under well known keys, eg `result` and `error`
    if (res[ERROR_KEY]) {
      log.warn('', `overwriting existing ${ERROR_KEY} on json output`)
    }
    res[ERROR_KEY] = getArrayOrObject(errors)
  }

  return res
}

const withMeta = (handler) => (level, ...args) => {
  let meta = {}
  const last = args.at(-1)
  if (last && typeof last === 'object' && Object.hasOwn(last, META)) {
    meta = args.pop()
  }
  return handler(level, meta, ...args)
}

class Display {
  #logState = {
    buffering: true,
    buffer: [],
  }

  #outputState = {
    buffering: true,
    buffer: [],
  }

  // colors
  #noColorChalk
  #stdoutChalk
  #stdoutColor
  #stderrChalk
  #stderrColor
  #logColors

  // progress
  #progress

  // options
  #command
  #levelIndex
  #timing
  #json
  #heading
  #silent

  // display streams
  #stdout
  #stderr

  constructor ({ stdout, stderr }) {
    this.#stdout = setBlocking(stdout)
    this.#stderr = setBlocking(stderr)

    // Handlers are set immediately so they can buffer all events
    process.on('log', this.#logHandler)
    process.on('output', this.#outputHandler)
    process.on('input', this.#inputHandler)
    this.#progress = new Progress({ stream: stderr })
  }

  off () {
    process.off('log', this.#logHandler)
    this.#logState.buffer.length = 0
    process.off('output', this.#outputHandler)
    this.#outputState.buffer.length = 0
    process.off('input', this.#inputHandler)
    this.#progress.off()
  }

  get chalk () {
    return {
      noColor: this.#noColorChalk,
      stdout: this.#stdoutChalk,
      stderr: this.#stderrChalk,
    }
  }

  async load ({
    command,
    heading,
    json,
    loglevel,
    progress,
    stderrColor,
    stdoutColor,
    timing,
    unicode,
  }) {
    // get createSupportsColor from chalk directly if this lands
    // https://github.com/chalk/chalk/pull/600
    const [{ Chalk }, { createSupportsColor }] = await Promise.all([
      import('chalk'),
      import('supports-color'),
    ])
    // we get the chalk level based on a null stream meaning chalk will only use
    // what it knows about the environment to get color support since we already
    // determined in our definitions that we want to show colors.
    const level = Math.max(createSupportsColor(null).level, 1)
    this.#noColorChalk = new Chalk({ level: 0 })
    this.#stdoutColor = stdoutColor
    this.#stdoutChalk = stdoutColor ? new Chalk({ level }) : this.#noColorChalk
    this.#stderrColor = stderrColor
    this.#stderrChalk = stderrColor ? new Chalk({ level }) : this.#noColorChalk
    this.#logColors = COLOR_PALETTE({ chalk: this.#stderrChalk })

    this.#command = command
    this.#levelIndex = LEVEL_OPTIONS[loglevel].index
    this.#timing = timing
    this.#json = json
    this.#heading = heading
    this.#silent = this.#levelIndex <= 0

    // Emit resume event on the logs which will flush output
    log.resume()
    output.flush()
    this.#progress.load({
      unicode,
      enabled: !!progress && !this.#silent,
    })
  }

  // STREAM WRITES

  // Write formatted and (non-)colorized output to streams
  #write (stream, options, ...args) {
    const colors = stream === this.#stdout ? this.#stdoutColor : this.#stderrColor
    const value = formatWithOptions({ colors, ...options }, ...args)
    this.#progress.write(() => stream.write(value))
  }

  // HANDLERS

  // Arrow function assigned to a private class field so it can be passed
  // directly as a listener and still reference "this"
  #logHandler = withMeta((level, meta, ...args) => {
    switch (level) {
      case log.KEYS.resume:
        this.#logState.buffering = false
        this.#logState.buffer.forEach((item) => this.#tryWriteLog(...item))
        this.#logState.buffer.length = 0
        break

      case log.KEYS.pause:
        this.#logState.buffering = true
        break

      default:
        if (this.#logState.buffering) {
          this.#logState.buffer.push([level, meta, ...args])
        } else {
          this.#tryWriteLog(level, meta, ...args)
        }
        break
    }
  })

  // Arrow function assigned to a private class field so it can be passed
  // directly as a listener and still reference "this"
  #outputHandler = withMeta((level, meta, ...args) => {
    this.#json = typeof meta.json === 'boolean' ? meta.json : this.#json
    switch (level) {
      case output.KEYS.flush: {
        this.#outputState.buffering = false
        if (this.#json) {
          const json = getJsonBuffer(meta, this.#outputState.buffer)
          if (json) {
            this.#writeOutput(output.KEYS.standard, meta, JSON.stringify(json, null, 2))
          }
        } else {
          this.#outputState.buffer.forEach((item) => this.#writeOutput(...item))
        }
        this.#outputState.buffer.length = 0
        break
      }

      case output.KEYS.buffer:
        this.#outputState.buffer.push([output.KEYS.standard, meta, ...args])
        break

      default:
        if (this.#outputState.buffering) {
          this.#outputState.buffer.push([level, meta, ...args])
        } else {
          // HACK: Check if the argument looks like a run-script banner. This can be
          // replaced with proc-log.META in @npmcli/run-script
          if (typeof args[0] === 'string' && args[0].startsWith('\n> ') && args[0].endsWith('\n')) {
            if (this.#silent || ['exec', 'explore'].includes(this.#command)) {
              // Silent mode and some specific commands always hide run script banners
              break
            } else if (this.#json) {
              // In json mode, change output to stderr since we dont want to break json
              // parsing on stdout if the user is piping to jq or something.
              // XXX: in a future (breaking?) change it might make sense for run-script to
              // always output these banners with proc-log.output.error if we think they
              // align closer with "logging" instead of "output"
              level = output.KEYS.error
            }
          }
          this.#writeOutput(level, meta, ...args)
        }
        break
    }
  })

  #inputHandler = withMeta((level, meta, ...args) => {
    switch (level) {
      case input.KEYS.start:
        log.pause()
        this.#outputState.buffering = true
        this.#progress.off()
        break

      case input.KEYS.end:
        log.resume()
        output.flush()
        this.#progress.resume()
        break

      case input.KEYS.read: {
        // The convention when calling input.read is to pass in a single fn that returns
        // the promise to await. resolve and reject are provided by proc-log
        const [res, rej, p] = args
        return input.start(() => p()
          .then(res)
          .catch(rej)
          // Any call to procLog.input.read will render a prompt to the user, so we always
          // add a single newline of output to stdout to move the cursor to the next line
          .finally(() => output.standard('')))
      }
    }
  })

  // OUTPUT

  #writeOutput (level, meta, ...args) {
    switch (level) {
      case output.KEYS.standard:
        this.#write(this.#stdout, {}, ...args)
        break

      case output.KEYS.error:
        this.#write(this.#stderr, {}, ...args)
        break
    }
  }

  // LOGS

  #tryWriteLog (level, meta, ...args) {
    try {
      // Also (and this is a really inexcusable kludge), we patch the
      // log.warn() method so that when we see a peerDep override
      // explanation from Arborist, we can replace the object with a
      // highly abbreviated explanation of what's being overridden.
      // TODO: this could probably be moved to arborist now that display is refactored
      const [heading, message, expl] = args
      if (level === log.KEYS.warn && heading === 'ERESOLVE' && expl && typeof expl === 'object') {
        this.#writeLog(level, meta, heading, message)
        this.#writeLog(level, meta, '', explain(expl, this.#stderrChalk, 2))
        return
      }
      this.#writeLog(level, meta, ...args)
    } catch (ex) {
      try {
        // if it crashed once, it might again!
        this.#writeLog(log.KEYS.verbose, meta, '', `attempt to log crashed`, ...args, ex)
      } catch (ex2) {
        // This happens if the object has an inspect method that crashes so just console.error
        // with the errors but don't do anything else that might error again.
        // eslint-disable-next-line no-console
        console.error(`attempt to log crashed`, ex, ex2)
      }
    }
  }

  #writeLog (level, meta, ...args) {
    const levelOpts = LEVEL_METHODS[level]
    const show = levelOpts.show ?? (({ index }) => levelOpts.index <= index)
    const force = meta.force && !this.#silent

    if (force || show({ index: this.#levelIndex, timing: this.#timing })) {
      // this mutates the array so we can pass args directly to format later
      const title = args.shift()
      const prefix = [
        this.#logColors.heading(this.#heading),
        this.#logColors[level](level),
        title ? this.#logColors.title(title) : null,
      ]
      this.#write(this.#stderr, { prefix }, ...args)
    }
  }
}

class Progress {
  // Taken from https://github.com/sindresorhus/cli-spinners
  // MIT License
  // Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
  static dots = { duration: 80, frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'] }
  static lines = { duration: 130, frames: ['-', '\\', '|', '/'] }

  #stream
  #spinner
  #enabled = false

  #frameIndex = 0
  #lastUpdate = 0
  #interval
  #timeout

  // We are rendering is enabled option is set and we are not waiting for the render timeout
  get #rendering () {
    return this.#enabled && !this.#timeout
  }

  // We are spinning if enabled option is set and the render interval has been set
  get #spinning () {
    return this.#enabled && this.#interval
  }

  constructor ({ stream }) {
    this.#stream = stream
  }

  load ({ enabled, unicode }) {
    this.#enabled = enabled
    this.#spinner = unicode ? Progress.dots : Progress.lines
    // Dont render the spinner for short durations
    this.#render(200)
  }

  off () {
    if (!this.#enabled) {
      return
    }
    clearTimeout(this.#timeout)
    this.#timeout = null
    clearInterval(this.#interval)
    this.#interval = null
    this.#frameIndex = 0
    this.#lastUpdate = 0
    this.#clearSpinner()
  }

  resume () {
    this.#render()
  }

  // If we are currenting rendering the spinner we clear it
  // before writing our line and then re-render the spinner after.
  // If not then all we need to do is write the line
  write (write) {
    if (this.#spinning) {
      this.#clearSpinner()
    }
    write()
    if (this.#spinning) {
      this.#render()
    }
  }

  #render (ms) {
    if (ms) {
      this.#timeout = setTimeout(() => {
        this.#timeout = null
        this.#renderSpinner()
      }, ms)
      // Make sure this timeout does not keep the process open
      this.#timeout.unref()
    } else {
      this.#renderSpinner()
    }
  }

  #renderSpinner () {
    if (!this.#rendering) {
      return
    }
    // We always attempt to render immediately but we only request to move to the next
    // frame if it has been longer than our spinner frame duration since our last update
    this.#renderFrame(Date.now() - this.#lastUpdate >= this.#spinner.duration)
    clearInterval(this.#interval)
    this.#interval = setInterval(() => this.#renderFrame(true), this.#spinner.duration)
  }

  #renderFrame (next) {
    if (next) {
      this.#lastUpdate = Date.now()
      this.#frameIndex++
      if (this.#frameIndex >= this.#spinner.frames.length) {
        this.#frameIndex = 0
      }
    }
    this.#clearSpinner()
    this.#stream.write(this.#spinner.frames[this.#frameIndex])
  }

  #clearSpinner () {
    // Move to the start of the line and clear the rest of the line
    this.#stream.cursorTo(0)
    this.#stream.clearLine(1)
  }
}

module.exports = Display

Youez - 2016 - github.com/yon3zu
LinuXploit