index.mjs 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824
  1. import Webpack from 'webpack';
  2. import { isMinimal } from 'std-env';
  3. import prettyTime from 'pretty-time';
  4. import path, { sep, delimiter } from 'path';
  5. import chalk from 'chalk';
  6. import _consola from 'consola';
  7. function first(arr) {
  8. return arr[0];
  9. }
  10. function last(arr) {
  11. return arr.length ? arr[arr.length - 1] : null;
  12. }
  13. function startCase(str) {
  14. return str[0].toUpperCase() + str.substr(1);
  15. }
  16. function firstMatch(regex, str) {
  17. const m = regex.exec(str);
  18. return m ? m[0] : null;
  19. }
  20. function hasValue(s) {
  21. return s && s.length;
  22. }
  23. function removeAfter(delimiter, str) {
  24. return first(str.split(delimiter)) || "";
  25. }
  26. function removeBefore(delimiter, str) {
  27. return last(str.split(delimiter)) || "";
  28. }
  29. function range(len) {
  30. const arr = [];
  31. for (let i = 0; i < len; i++) {
  32. arr.push(i);
  33. }
  34. return arr;
  35. }
  36. function shortenPath(path = "") {
  37. const cwd = process.cwd() + sep;
  38. return String(path).replace(cwd, "");
  39. }
  40. function objectValues(obj) {
  41. return Object.keys(obj).map((key) => obj[key]);
  42. }
  43. /**
  44. * @typedef MarkdownTableOptions
  45. * @property {string|null|Array.<string|null|undefined>} [align]
  46. * @property {boolean} [padding=true]
  47. * @property {boolean} [delimiterStart=true]
  48. * @property {boolean} [delimiterStart=true]
  49. * @property {boolean} [delimiterEnd=true]
  50. * @property {boolean} [alignDelimiters=true]
  51. * @property {(value: string) => number} [stringLength]
  52. */
  53. /**
  54. * Create a table from a matrix of strings.
  55. *
  56. * @param {Array.<Array.<string|null|undefined>>} table
  57. * @param {MarkdownTableOptions} [options]
  58. * @returns {string}
  59. */
  60. function markdownTable(table, options) {
  61. const settings = options || {};
  62. const align = (settings.align || []).concat();
  63. const stringLength = settings.stringLength || defaultStringLength;
  64. /** @type {number[]} Character codes as symbols for alignment per column. */
  65. const alignments = [];
  66. let rowIndex = -1;
  67. /** @type {string[][]} Cells per row. */
  68. const cellMatrix = [];
  69. /** @type {number[][]} Sizes of each cell per row. */
  70. const sizeMatrix = [];
  71. /** @type {number[]} */
  72. const longestCellByColumn = [];
  73. let mostCellsPerRow = 0;
  74. /** @type {number} */
  75. let columnIndex;
  76. /** @type {string[]} Cells of current row */
  77. let row;
  78. /** @type {number[]} Sizes of current row */
  79. let sizes;
  80. /** @type {number} Sizes of current cell */
  81. let size;
  82. /** @type {string} Current cell */
  83. let cell;
  84. /** @type {string[]} Chunks of current line. */
  85. let line;
  86. /** @type {string} */
  87. let before;
  88. /** @type {string} */
  89. let after;
  90. /** @type {number} */
  91. let code;
  92. // This is a superfluous loop if we don’t align delimiters, but otherwise we’d
  93. // do superfluous work when aligning, so optimize for aligning.
  94. while (++rowIndex < table.length) {
  95. columnIndex = -1;
  96. row = [];
  97. sizes = [];
  98. if (table[rowIndex].length > mostCellsPerRow) {
  99. mostCellsPerRow = table[rowIndex].length;
  100. }
  101. while (++columnIndex < table[rowIndex].length) {
  102. cell = serialize(table[rowIndex][columnIndex]);
  103. if (settings.alignDelimiters !== false) {
  104. size = stringLength(cell);
  105. sizes[columnIndex] = size;
  106. if (
  107. longestCellByColumn[columnIndex] === undefined ||
  108. size > longestCellByColumn[columnIndex]
  109. ) {
  110. longestCellByColumn[columnIndex] = size;
  111. }
  112. }
  113. row.push(cell);
  114. }
  115. cellMatrix[rowIndex] = row;
  116. sizeMatrix[rowIndex] = sizes;
  117. }
  118. // Figure out which alignments to use.
  119. columnIndex = -1;
  120. if (typeof align === 'object' && 'length' in align) {
  121. while (++columnIndex < mostCellsPerRow) {
  122. alignments[columnIndex] = toAlignment(align[columnIndex]);
  123. }
  124. } else {
  125. code = toAlignment(align);
  126. while (++columnIndex < mostCellsPerRow) {
  127. alignments[columnIndex] = code;
  128. }
  129. }
  130. // Inject the alignment row.
  131. columnIndex = -1;
  132. row = [];
  133. sizes = [];
  134. while (++columnIndex < mostCellsPerRow) {
  135. code = alignments[columnIndex];
  136. before = '';
  137. after = '';
  138. if (code === 99 /* `c` */) {
  139. before = ':';
  140. after = ':';
  141. } else if (code === 108 /* `l` */) {
  142. before = ':';
  143. } else if (code === 114 /* `r` */) {
  144. after = ':';
  145. }
  146. // There *must* be at least one hyphen-minus in each alignment cell.
  147. size =
  148. settings.alignDelimiters === false
  149. ? 1
  150. : Math.max(
  151. 1,
  152. longestCellByColumn[columnIndex] - before.length - after.length
  153. );
  154. cell = before + '-'.repeat(size) + after;
  155. if (settings.alignDelimiters !== false) {
  156. size = before.length + size + after.length;
  157. if (size > longestCellByColumn[columnIndex]) {
  158. longestCellByColumn[columnIndex] = size;
  159. }
  160. sizes[columnIndex] = size;
  161. }
  162. row[columnIndex] = cell;
  163. }
  164. // Inject the alignment row.
  165. cellMatrix.splice(1, 0, row);
  166. sizeMatrix.splice(1, 0, sizes);
  167. rowIndex = -1;
  168. /** @type {string[]} */
  169. const lines = [];
  170. while (++rowIndex < cellMatrix.length) {
  171. row = cellMatrix[rowIndex];
  172. sizes = sizeMatrix[rowIndex];
  173. columnIndex = -1;
  174. line = [];
  175. while (++columnIndex < mostCellsPerRow) {
  176. cell = row[columnIndex] || '';
  177. before = '';
  178. after = '';
  179. if (settings.alignDelimiters !== false) {
  180. size = longestCellByColumn[columnIndex] - (sizes[columnIndex] || 0);
  181. code = alignments[columnIndex];
  182. if (code === 114 /* `r` */) {
  183. before = ' '.repeat(size);
  184. } else if (code === 99 /* `c` */) {
  185. if (size % 2) {
  186. before = ' '.repeat(size / 2 + 0.5);
  187. after = ' '.repeat(size / 2 - 0.5);
  188. } else {
  189. before = ' '.repeat(size / 2);
  190. after = before;
  191. }
  192. } else {
  193. after = ' '.repeat(size);
  194. }
  195. }
  196. if (settings.delimiterStart !== false && !columnIndex) {
  197. line.push('|');
  198. }
  199. if (
  200. settings.padding !== false &&
  201. // Don’t add the opening space if we’re not aligning and the cell is
  202. // empty: there will be a closing space.
  203. !(settings.alignDelimiters === false && cell === '') &&
  204. (settings.delimiterStart !== false || columnIndex)
  205. ) {
  206. line.push(' ');
  207. }
  208. if (settings.alignDelimiters !== false) {
  209. line.push(before);
  210. }
  211. line.push(cell);
  212. if (settings.alignDelimiters !== false) {
  213. line.push(after);
  214. }
  215. if (settings.padding !== false) {
  216. line.push(' ');
  217. }
  218. if (
  219. settings.delimiterEnd !== false ||
  220. columnIndex !== mostCellsPerRow - 1
  221. ) {
  222. line.push('|');
  223. }
  224. }
  225. lines.push(
  226. settings.delimiterEnd === false
  227. ? line.join('').replace(/ +$/, '')
  228. : line.join('')
  229. );
  230. }
  231. return lines.join('\n')
  232. }
  233. /**
  234. * @param {string|null|undefined} [value]
  235. * @returns {string}
  236. */
  237. function serialize(value) {
  238. return value === null || value === undefined ? '' : String(value)
  239. }
  240. /**
  241. * @param {string} value
  242. * @returns {number}
  243. */
  244. function defaultStringLength(value) {
  245. return value.length
  246. }
  247. /**
  248. * @param {string|null|undefined} value
  249. * @returns {number}
  250. */
  251. function toAlignment(value) {
  252. const code = typeof value === 'string' ? value.charCodeAt(0) : 0;
  253. return code === 67 /* `C` */ || code === 99 /* `c` */
  254. ? 99 /* `c` */
  255. : code === 76 /* `L` */ || code === 108 /* `l` */
  256. ? 108 /* `l` */
  257. : code === 82 /* `R` */ || code === 114 /* `r` */
  258. ? 114 /* `r` */
  259. : 0
  260. }
  261. function isUnicodeSupported() {
  262. if (process.platform !== 'win32') {
  263. return process.env.TERM !== 'linux'; // Linux console (kernel)
  264. }
  265. return Boolean(process.env.CI) ||
  266. Boolean(process.env.WT_SESSION) || // Windows Terminal
  267. process.env.ConEmuTask === '{cmd::Cmder}' || // ConEmu and cmder
  268. process.env.TERM_PROGRAM === 'vscode' ||
  269. process.env.TERM === 'xterm-256color' ||
  270. process.env.TERM === 'alacritty';
  271. }
  272. const {platform} = process;
  273. const common = {
  274. square: '█',
  275. squareDarkShade: '▓',
  276. squareMediumShade: '▒',
  277. squareLightShade: '░',
  278. squareTop: '▀',
  279. squareBottom: '▄',
  280. squareLeft: '▌',
  281. squareRight: '▐',
  282. squareCenter: '■',
  283. bullet: '●',
  284. dot: '․',
  285. ellipsis: '…',
  286. pointerSmall: '›',
  287. triangleUp: '▲',
  288. triangleUpSmall: '▴',
  289. triangleDown: '▼',
  290. triangleDownSmall: '▾',
  291. triangleLeftSmall: '◂',
  292. triangleRightSmall: '▸',
  293. home: '⌂',
  294. heart: '♥',
  295. musicNote: '♪',
  296. musicNoteBeamed: '♫',
  297. arrowUp: '↑',
  298. arrowDown: '↓',
  299. arrowLeft: '←',
  300. arrowRight: '→',
  301. arrowLeftRight: '↔',
  302. arrowUpDown: '↕',
  303. almostEqual: '≈',
  304. notEqual: '≠',
  305. lessOrEqual: '≤',
  306. greaterOrEqual: '≥',
  307. identical: '≡',
  308. infinity: '∞',
  309. subscriptZero: '₀',
  310. subscriptOne: '₁',
  311. subscriptTwo: '₂',
  312. subscriptThree: '₃',
  313. subscriptFour: '₄',
  314. subscriptFive: '₅',
  315. subscriptSix: '₆',
  316. subscriptSeven: '₇',
  317. subscriptEight: '₈',
  318. subscriptNine: '₉',
  319. oneHalf: '½',
  320. oneThird: '⅓',
  321. oneQuarter: '¼',
  322. oneFifth: '⅕',
  323. oneSixth: '⅙',
  324. oneEighth: '⅛',
  325. twoThirds: '⅔',
  326. twoFifths: '⅖',
  327. threeQuarters: '¾',
  328. threeFifths: '⅗',
  329. threeEighths: '⅜',
  330. fourFifths: '⅘',
  331. fiveSixths: '⅚',
  332. fiveEighths: '⅝',
  333. sevenEighths: '⅞',
  334. line: '─',
  335. lineBold: '━',
  336. lineDouble: '═',
  337. lineDashed0: '┄',
  338. lineDashed1: '┅',
  339. lineDashed2: '┈',
  340. lineDashed3: '┉',
  341. lineDashed4: '╌',
  342. lineDashed5: '╍',
  343. lineDashed6: '╴',
  344. lineDashed7: '╶',
  345. lineDashed8: '╸',
  346. lineDashed9: '╺',
  347. lineDashed10: '╼',
  348. lineDashed11: '╾',
  349. lineDashed12: '−',
  350. lineDashed13: '–',
  351. lineDashed14: '‐',
  352. lineDashed15: '⁃',
  353. lineVertical: '│',
  354. lineVerticalBold: '┃',
  355. lineVerticalDouble: '║',
  356. lineVerticalDashed0: '┆',
  357. lineVerticalDashed1: '┇',
  358. lineVerticalDashed2: '┊',
  359. lineVerticalDashed3: '┋',
  360. lineVerticalDashed4: '╎',
  361. lineVerticalDashed5: '╏',
  362. lineVerticalDashed6: '╵',
  363. lineVerticalDashed7: '╷',
  364. lineVerticalDashed8: '╹',
  365. lineVerticalDashed9: '╻',
  366. lineVerticalDashed10: '╽',
  367. lineVerticalDashed11: '╿',
  368. lineDownLeft: '┐',
  369. lineDownLeftArc: '╮',
  370. lineDownBoldLeftBold: '┓',
  371. lineDownBoldLeft: '┒',
  372. lineDownLeftBold: '┑',
  373. lineDownDoubleLeftDouble: '╗',
  374. lineDownDoubleLeft: '╖',
  375. lineDownLeftDouble: '╕',
  376. lineDownRight: '┌',
  377. lineDownRightArc: '╭',
  378. lineDownBoldRightBold: '┏',
  379. lineDownBoldRight: '┎',
  380. lineDownRightBold: '┍',
  381. lineDownDoubleRightDouble: '╔',
  382. lineDownDoubleRight: '╓',
  383. lineDownRightDouble: '╒',
  384. lineUpLeft: '┘',
  385. lineUpLeftArc: '╯',
  386. lineUpBoldLeftBold: '┛',
  387. lineUpBoldLeft: '┚',
  388. lineUpLeftBold: '┙',
  389. lineUpDoubleLeftDouble: '╝',
  390. lineUpDoubleLeft: '╜',
  391. lineUpLeftDouble: '╛',
  392. lineUpRight: '└',
  393. lineUpRightArc: '╰',
  394. lineUpBoldRightBold: '┗',
  395. lineUpBoldRight: '┖',
  396. lineUpRightBold: '┕',
  397. lineUpDoubleRightDouble: '╚',
  398. lineUpDoubleRight: '╙',
  399. lineUpRightDouble: '╘',
  400. lineUpDownLeft: '┤',
  401. lineUpBoldDownBoldLeftBold: '┫',
  402. lineUpBoldDownBoldLeft: '┨',
  403. lineUpDownLeftBold: '┥',
  404. lineUpBoldDownLeftBold: '┩',
  405. lineUpDownBoldLeftBold: '┪',
  406. lineUpDownBoldLeft: '┧',
  407. lineUpBoldDownLeft: '┦',
  408. lineUpDoubleDownDoubleLeftDouble: '╣',
  409. lineUpDoubleDownDoubleLeft: '╢',
  410. lineUpDownLeftDouble: '╡',
  411. lineUpDownRight: '├',
  412. lineUpBoldDownBoldRightBold: '┣',
  413. lineUpBoldDownBoldRight: '┠',
  414. lineUpDownRightBold: '┝',
  415. lineUpBoldDownRightBold: '┡',
  416. lineUpDownBoldRightBold: '┢',
  417. lineUpDownBoldRight: '┟',
  418. lineUpBoldDownRight: '┞',
  419. lineUpDoubleDownDoubleRightDouble: '╠',
  420. lineUpDoubleDownDoubleRight: '╟',
  421. lineUpDownRightDouble: '╞',
  422. lineDownLeftRight: '┬',
  423. lineDownBoldLeftBoldRightBold: '┳',
  424. lineDownLeftBoldRightBold: '┯',
  425. lineDownBoldLeftRight: '┰',
  426. lineDownBoldLeftBoldRight: '┱',
  427. lineDownBoldLeftRightBold: '┲',
  428. lineDownLeftRightBold: '┮',
  429. lineDownLeftBoldRight: '┭',
  430. lineDownDoubleLeftDoubleRightDouble: '╦',
  431. lineDownDoubleLeftRight: '╥',
  432. lineDownLeftDoubleRightDouble: '╤',
  433. lineUpLeftRight: '┴',
  434. lineUpBoldLeftBoldRightBold: '┻',
  435. lineUpLeftBoldRightBold: '┷',
  436. lineUpBoldLeftRight: '┸',
  437. lineUpBoldLeftBoldRight: '┹',
  438. lineUpBoldLeftRightBold: '┺',
  439. lineUpLeftRightBold: '┶',
  440. lineUpLeftBoldRight: '┵',
  441. lineUpDoubleLeftDoubleRightDouble: '╩',
  442. lineUpDoubleLeftRight: '╨',
  443. lineUpLeftDoubleRightDouble: '╧',
  444. lineUpDownLeftRight: '┼',
  445. lineUpBoldDownBoldLeftBoldRightBold: '╋',
  446. lineUpDownBoldLeftBoldRightBold: '╈',
  447. lineUpBoldDownLeftBoldRightBold: '╇',
  448. lineUpBoldDownBoldLeftRightBold: '╊',
  449. lineUpBoldDownBoldLeftBoldRight: '╉',
  450. lineUpBoldDownLeftRight: '╀',
  451. lineUpDownBoldLeftRight: '╁',
  452. lineUpDownLeftBoldRight: '┽',
  453. lineUpDownLeftRightBold: '┾',
  454. lineUpBoldDownBoldLeftRight: '╂',
  455. lineUpDownLeftBoldRightBold: '┿',
  456. lineUpBoldDownLeftBoldRight: '╃',
  457. lineUpBoldDownLeftRightBold: '╄',
  458. lineUpDownBoldLeftBoldRight: '╅',
  459. lineUpDownBoldLeftRightBold: '╆',
  460. lineUpDoubleDownDoubleLeftDoubleRightDouble: '╬',
  461. lineUpDoubleDownDoubleLeftRight: '╫',
  462. lineUpDownLeftDoubleRightDouble: '╪',
  463. lineCross: '╳',
  464. lineBackslash: '╲',
  465. lineSlash: '╱'
  466. };
  467. const mainSymbols = {
  468. ...common,
  469. // The main symbols for those do not look that good on Ubuntu.
  470. ...(
  471. platform === 'linux' ?
  472. {
  473. circleQuestionMark: '?⃝',
  474. questionMarkPrefix: '?⃝'
  475. } :
  476. {
  477. circleQuestionMark: '?',
  478. questionMarkPrefix: '?'
  479. }
  480. ),
  481. tick: '✔',
  482. info: 'ℹ',
  483. warning: '⚠',
  484. cross: '✖',
  485. squareSmall: '◻',
  486. squareSmallFilled: '◼',
  487. circle: '◯',
  488. circleFilled: '◉',
  489. circleDotted: '◌',
  490. circleDouble: '◎',
  491. circleCircle: 'ⓞ',
  492. circleCross: 'ⓧ',
  493. circlePipe: 'Ⓘ',
  494. radioOn: '◉',
  495. radioOff: '◯',
  496. checkboxOn: '☒',
  497. checkboxOff: '☐',
  498. checkboxCircleOn: 'ⓧ',
  499. checkboxCircleOff: 'Ⓘ',
  500. pointer: '❯',
  501. triangleUpOutline: '△',
  502. triangleLeft: '◀',
  503. triangleRight: '▶',
  504. lozenge: '◆',
  505. lozengeOutline: '◇',
  506. hamburger: '☰',
  507. smiley: '㋡',
  508. mustache: '෴',
  509. star: '★',
  510. play: '▶',
  511. nodejs: '⬢',
  512. oneSeventh: '⅐',
  513. oneNinth: '⅑',
  514. oneTenth: '⅒'
  515. };
  516. const fallbackSymbols = {
  517. ...common,
  518. tick: '√',
  519. info: 'i',
  520. warning: '‼',
  521. cross: '×',
  522. squareSmall: '□',
  523. squareSmallFilled: '■',
  524. circle: '( )',
  525. circleFilled: '(*)',
  526. circleDotted: '( )',
  527. circleDouble: '( )',
  528. circleCircle: '(○)',
  529. circleCross: '(×)',
  530. circlePipe: '(│)',
  531. circleQuestionMark: '(?)',
  532. radioOn: '(*)',
  533. radioOff: '( )',
  534. checkboxOn: '[×]',
  535. checkboxOff: '[ ]',
  536. checkboxCircleOn: '(×)',
  537. checkboxCircleOff: '( )',
  538. questionMarkPrefix: '?',
  539. pointer: '>',
  540. triangleUpOutline: '∆',
  541. triangleLeft: '◄',
  542. triangleRight: '►',
  543. lozenge: '♦',
  544. lozengeOutline: '◊',
  545. hamburger: '≡',
  546. smiley: '☺',
  547. mustache: '┌─┐',
  548. star: '✶',
  549. play: '►',
  550. nodejs: '♦',
  551. oneSeventh: '1/7',
  552. oneNinth: '1/9',
  553. oneTenth: '1/10'
  554. };
  555. const shouldUseMain = isUnicodeSupported();
  556. const figures = shouldUseMain ? mainSymbols : fallbackSymbols;
  557. const { bullet, tick, cross, pointerSmall, radioOff } = figures;
  558. const nodeModules = `${delimiter}node_modules${delimiter}`;
  559. const BAR_LENGTH = 25;
  560. const BLOCK_CHAR = "\u2588";
  561. const BLOCK_CHAR2 = "\u2588";
  562. const NEXT = " " + chalk.blue(pointerSmall) + " ";
  563. const BULLET = bullet;
  564. const TICK = tick;
  565. const CROSS = cross;
  566. const CIRCLE_OPEN = radioOff;
  567. const consola = _consola.withTag("webpackbar");
  568. const colorize = (color) => {
  569. if (color[0] === "#") {
  570. return chalk.hex(color);
  571. }
  572. return chalk[color] || chalk.keyword(color);
  573. };
  574. const renderBar = (progress, color) => {
  575. const w = progress * (BAR_LENGTH / 100);
  576. const bg = chalk.white(BLOCK_CHAR);
  577. const fg = colorize(color)(BLOCK_CHAR2);
  578. return range(BAR_LENGTH).map((i) => i < w ? fg : bg).join("");
  579. };
  580. function createTable(data) {
  581. return markdownTable(data);
  582. }
  583. function ellipsisLeft(str, n) {
  584. if (str.length <= n - 3) {
  585. return str;
  586. }
  587. return `...${str.substr(str.length - n - 1)}`;
  588. }
  589. const parseRequest = (requestStr) => {
  590. const parts = (requestStr || "").split("!");
  591. const file = path.relative(process.cwd(), removeAfter("?", removeBefore(nodeModules, parts.pop())));
  592. const loaders = parts.map((part) => firstMatch(/[a-z0-9-@]+-loader/, part)).filter(hasValue);
  593. return {
  594. file: hasValue(file) ? file : null,
  595. loaders
  596. };
  597. };
  598. const formatRequest = (request) => {
  599. const loaders = request.loaders.join(NEXT);
  600. if (!loaders.length) {
  601. return request.file || "";
  602. }
  603. return `${loaders}${NEXT}${request.file}`;
  604. };
  605. function hook(compiler, hookName, fn) {
  606. if (compiler.hooks) {
  607. compiler.hooks[hookName].tap("WebpackBar:" + hookName, fn);
  608. } else {
  609. compiler.plugin(hookName, fn);
  610. }
  611. }
  612. const ESC = '\u001B[';
  613. const OSC = '\u001B]';
  614. const BEL = '\u0007';
  615. const SEP = ';';
  616. const isTerminalApp = process.env.TERM_PROGRAM === 'Apple_Terminal';
  617. const ansiEscapes = {};
  618. ansiEscapes.cursorTo = (x, y) => {
  619. if (typeof x !== 'number') {
  620. throw new TypeError('The `x` argument is required');
  621. }
  622. if (typeof y !== 'number') {
  623. return ESC + (x + 1) + 'G';
  624. }
  625. return ESC + (y + 1) + ';' + (x + 1) + 'H';
  626. };
  627. ansiEscapes.cursorMove = (x, y) => {
  628. if (typeof x !== 'number') {
  629. throw new TypeError('The `x` argument is required');
  630. }
  631. let returnValue = '';
  632. if (x < 0) {
  633. returnValue += ESC + (-x) + 'D';
  634. } else if (x > 0) {
  635. returnValue += ESC + x + 'C';
  636. }
  637. if (y < 0) {
  638. returnValue += ESC + (-y) + 'A';
  639. } else if (y > 0) {
  640. returnValue += ESC + y + 'B';
  641. }
  642. return returnValue;
  643. };
  644. ansiEscapes.cursorUp = (count = 1) => ESC + count + 'A';
  645. ansiEscapes.cursorDown = (count = 1) => ESC + count + 'B';
  646. ansiEscapes.cursorForward = (count = 1) => ESC + count + 'C';
  647. ansiEscapes.cursorBackward = (count = 1) => ESC + count + 'D';
  648. ansiEscapes.cursorLeft = ESC + 'G';
  649. ansiEscapes.cursorSavePosition = isTerminalApp ? '\u001B7' : ESC + 's';
  650. ansiEscapes.cursorRestorePosition = isTerminalApp ? '\u001B8' : ESC + 'u';
  651. ansiEscapes.cursorGetPosition = ESC + '6n';
  652. ansiEscapes.cursorNextLine = ESC + 'E';
  653. ansiEscapes.cursorPrevLine = ESC + 'F';
  654. ansiEscapes.cursorHide = ESC + '?25l';
  655. ansiEscapes.cursorShow = ESC + '?25h';
  656. ansiEscapes.eraseLines = count => {
  657. let clear = '';
  658. for (let i = 0; i < count; i++) {
  659. clear += ansiEscapes.eraseLine + (i < count - 1 ? ansiEscapes.cursorUp() : '');
  660. }
  661. if (count) {
  662. clear += ansiEscapes.cursorLeft;
  663. }
  664. return clear;
  665. };
  666. ansiEscapes.eraseEndLine = ESC + 'K';
  667. ansiEscapes.eraseStartLine = ESC + '1K';
  668. ansiEscapes.eraseLine = ESC + '2K';
  669. ansiEscapes.eraseDown = ESC + 'J';
  670. ansiEscapes.eraseUp = ESC + '1J';
  671. ansiEscapes.eraseScreen = ESC + '2J';
  672. ansiEscapes.scrollUp = ESC + 'S';
  673. ansiEscapes.scrollDown = ESC + 'T';
  674. ansiEscapes.clearScreen = '\u001Bc';
  675. ansiEscapes.clearTerminal = process.platform === 'win32' ?
  676. `${ansiEscapes.eraseScreen}${ESC}0f` :
  677. // 1. Erases the screen (Only done in case `2` is not supported)
  678. // 2. Erases the whole screen including scrollback buffer
  679. // 3. Moves cursor to the top-left position
  680. // More info: https://www.real-world-systems.com/docs/ANSIcode.html
  681. `${ansiEscapes.eraseScreen}${ESC}3J${ESC}H`;
  682. ansiEscapes.beep = BEL;
  683. ansiEscapes.link = (text, url) => {
  684. return [
  685. OSC,
  686. '8',
  687. SEP,
  688. SEP,
  689. url,
  690. BEL,
  691. text,
  692. OSC,
  693. '8',
  694. SEP,
  695. SEP,
  696. BEL
  697. ].join('');
  698. };
  699. ansiEscapes.image = (buffer, options = {}) => {
  700. let returnValue = `${OSC}1337;File=inline=1`;
  701. if (options.width) {
  702. returnValue += `;width=${options.width}`;
  703. }
  704. if (options.height) {
  705. returnValue += `;height=${options.height}`;
  706. }
  707. if (options.preserveAspectRatio === false) {
  708. returnValue += ';preserveAspectRatio=0';
  709. }
  710. return returnValue + ':' + buffer.toString('base64') + BEL;
  711. };
  712. ansiEscapes.iTerm = {
  713. setCwd: (cwd = process.cwd()) => `${OSC}50;CurrentDir=${cwd}${BEL}`,
  714. annotation: (message, options = {}) => {
  715. let returnValue = `${OSC}1337;`;
  716. const hasX = typeof options.x !== 'undefined';
  717. const hasY = typeof options.y !== 'undefined';
  718. if ((hasX || hasY) && !(hasX && hasY && typeof options.length !== 'undefined')) {
  719. throw new Error('`x`, `y` and `length` must be defined when `x` or `y` is defined');
  720. }
  721. message = message.replace(/\|/g, '');
  722. returnValue += options.isHidden ? 'AddHiddenAnnotation=' : 'AddAnnotation=';
  723. if (options.length > 0) {
  724. returnValue +=
  725. (hasX ?
  726. [message, options.length, options.x, options.y] :
  727. [options.length, message]).join('|');
  728. } else {
  729. returnValue += message;
  730. }
  731. return returnValue + BEL;
  732. }
  733. };
  734. function ansiRegex({onlyFirst = false} = {}) {
  735. const pattern = [
  736. '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
  737. '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))'
  738. ].join('|');
  739. return new RegExp(pattern, onlyFirst ? undefined : 'g');
  740. }
  741. function stripAnsi(string) {
  742. if (typeof string !== 'string') {
  743. throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
  744. }
  745. return string.replace(ansiRegex(), '');
  746. }
  747. /* eslint-disable yoda */
  748. function isFullwidthCodePoint(codePoint) {
  749. if (!Number.isInteger(codePoint)) {
  750. return false;
  751. }
  752. // Code points are derived from:
  753. // https://unicode.org/Public/UNIDATA/EastAsianWidth.txt
  754. return codePoint >= 0x1100 && (
  755. codePoint <= 0x115F || // Hangul Jamo
  756. codePoint === 0x2329 || // LEFT-POINTING ANGLE BRACKET
  757. codePoint === 0x232A || // RIGHT-POINTING ANGLE BRACKET
  758. // CJK Radicals Supplement .. Enclosed CJK Letters and Months
  759. (0x2E80 <= codePoint && codePoint <= 0x3247 && codePoint !== 0x303F) ||
  760. // Enclosed CJK Letters and Months .. CJK Unified Ideographs Extension A
  761. (0x3250 <= codePoint && codePoint <= 0x4DBF) ||
  762. // CJK Unified Ideographs .. Yi Radicals
  763. (0x4E00 <= codePoint && codePoint <= 0xA4C6) ||
  764. // Hangul Jamo Extended-A
  765. (0xA960 <= codePoint && codePoint <= 0xA97C) ||
  766. // Hangul Syllables
  767. (0xAC00 <= codePoint && codePoint <= 0xD7A3) ||
  768. // CJK Compatibility Ideographs
  769. (0xF900 <= codePoint && codePoint <= 0xFAFF) ||
  770. // Vertical Forms
  771. (0xFE10 <= codePoint && codePoint <= 0xFE19) ||
  772. // CJK Compatibility Forms .. Small Form Variants
  773. (0xFE30 <= codePoint && codePoint <= 0xFE6B) ||
  774. // Halfwidth and Fullwidth Forms
  775. (0xFF01 <= codePoint && codePoint <= 0xFF60) ||
  776. (0xFFE0 <= codePoint && codePoint <= 0xFFE6) ||
  777. // Kana Supplement
  778. (0x1B000 <= codePoint && codePoint <= 0x1B001) ||
  779. // Enclosed Ideographic Supplement
  780. (0x1F200 <= codePoint && codePoint <= 0x1F251) ||
  781. // CJK Unified Ideographs Extension B .. Tertiary Ideographic Plane
  782. (0x20000 <= codePoint && codePoint <= 0x3FFFD)
  783. );
  784. }
  785. var emojiRegex = function () {
  786. // https://mths.be/emoji
  787. return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g;
  788. };
  789. function stringWidth(string) {
  790. if (typeof string !== 'string' || string.length === 0) {
  791. return 0;
  792. }
  793. string = stripAnsi(string);
  794. if (string.length === 0) {
  795. return 0;
  796. }
  797. string = string.replace(emojiRegex(), ' ');
  798. let width = 0;
  799. for (let index = 0; index < string.length; index++) {
  800. const codePoint = string.codePointAt(index);
  801. // Ignore control characters
  802. if (codePoint <= 0x1F || (codePoint >= 0x7F && codePoint <= 0x9F)) {
  803. continue;
  804. }
  805. // Ignore combining characters
  806. if (codePoint >= 0x300 && codePoint <= 0x36F) {
  807. continue;
  808. }
  809. // Surrogates
  810. if (codePoint > 0xFFFF) {
  811. index++;
  812. }
  813. width += isFullwidthCodePoint(codePoint) ? 2 : 1;
  814. }
  815. return width;
  816. }
  817. const ANSI_BACKGROUND_OFFSET = 10;
  818. const wrapAnsi16 = (offset = 0) => code => `\u001B[${code + offset}m`;
  819. const wrapAnsi256 = (offset = 0) => code => `\u001B[${38 + offset};5;${code}m`;
  820. const wrapAnsi16m = (offset = 0) => (red, green, blue) => `\u001B[${38 + offset};2;${red};${green};${blue}m`;
  821. function assembleStyles() {
  822. const codes = new Map();
  823. const styles = {
  824. modifier: {
  825. reset: [0, 0],
  826. // 21 isn't widely supported and 22 does the same thing
  827. bold: [1, 22],
  828. dim: [2, 22],
  829. italic: [3, 23],
  830. underline: [4, 24],
  831. overline: [53, 55],
  832. inverse: [7, 27],
  833. hidden: [8, 28],
  834. strikethrough: [9, 29]
  835. },
  836. color: {
  837. black: [30, 39],
  838. red: [31, 39],
  839. green: [32, 39],
  840. yellow: [33, 39],
  841. blue: [34, 39],
  842. magenta: [35, 39],
  843. cyan: [36, 39],
  844. white: [37, 39],
  845. // Bright color
  846. blackBright: [90, 39],
  847. redBright: [91, 39],
  848. greenBright: [92, 39],
  849. yellowBright: [93, 39],
  850. blueBright: [94, 39],
  851. magentaBright: [95, 39],
  852. cyanBright: [96, 39],
  853. whiteBright: [97, 39]
  854. },
  855. bgColor: {
  856. bgBlack: [40, 49],
  857. bgRed: [41, 49],
  858. bgGreen: [42, 49],
  859. bgYellow: [43, 49],
  860. bgBlue: [44, 49],
  861. bgMagenta: [45, 49],
  862. bgCyan: [46, 49],
  863. bgWhite: [47, 49],
  864. // Bright color
  865. bgBlackBright: [100, 49],
  866. bgRedBright: [101, 49],
  867. bgGreenBright: [102, 49],
  868. bgYellowBright: [103, 49],
  869. bgBlueBright: [104, 49],
  870. bgMagentaBright: [105, 49],
  871. bgCyanBright: [106, 49],
  872. bgWhiteBright: [107, 49]
  873. }
  874. };
  875. // Alias bright black as gray (and grey)
  876. styles.color.gray = styles.color.blackBright;
  877. styles.bgColor.bgGray = styles.bgColor.bgBlackBright;
  878. styles.color.grey = styles.color.blackBright;
  879. styles.bgColor.bgGrey = styles.bgColor.bgBlackBright;
  880. for (const [groupName, group] of Object.entries(styles)) {
  881. for (const [styleName, style] of Object.entries(group)) {
  882. styles[styleName] = {
  883. open: `\u001B[${style[0]}m`,
  884. close: `\u001B[${style[1]}m`
  885. };
  886. group[styleName] = styles[styleName];
  887. codes.set(style[0], style[1]);
  888. }
  889. Object.defineProperty(styles, groupName, {
  890. value: group,
  891. enumerable: false
  892. });
  893. }
  894. Object.defineProperty(styles, 'codes', {
  895. value: codes,
  896. enumerable: false
  897. });
  898. styles.color.close = '\u001B[39m';
  899. styles.bgColor.close = '\u001B[49m';
  900. styles.color.ansi = wrapAnsi16();
  901. styles.color.ansi256 = wrapAnsi256();
  902. styles.color.ansi16m = wrapAnsi16m();
  903. styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
  904. styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
  905. styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
  906. // From https://github.com/Qix-/color-convert/blob/3f0e0d4e92e235796ccb17f6e85c72094a651f49/conversions.js
  907. Object.defineProperties(styles, {
  908. rgbToAnsi256: {
  909. value: (red, green, blue) => {
  910. // We use the extended greyscale palette here, with the exception of
  911. // black and white. normal palette only has 4 greyscale shades.
  912. if (red === green && green === blue) {
  913. if (red < 8) {
  914. return 16;
  915. }
  916. if (red > 248) {
  917. return 231;
  918. }
  919. return Math.round(((red - 8) / 247) * 24) + 232;
  920. }
  921. return 16 +
  922. (36 * Math.round(red / 255 * 5)) +
  923. (6 * Math.round(green / 255 * 5)) +
  924. Math.round(blue / 255 * 5);
  925. },
  926. enumerable: false
  927. },
  928. hexToRgb: {
  929. value: hex => {
  930. const matches = /(?<colorString>[a-f\d]{6}|[a-f\d]{3})/i.exec(hex.toString(16));
  931. if (!matches) {
  932. return [0, 0, 0];
  933. }
  934. let {colorString} = matches.groups;
  935. if (colorString.length === 3) {
  936. colorString = colorString.split('').map(character => character + character).join('');
  937. }
  938. const integer = Number.parseInt(colorString, 16);
  939. return [
  940. (integer >> 16) & 0xFF,
  941. (integer >> 8) & 0xFF,
  942. integer & 0xFF
  943. ];
  944. },
  945. enumerable: false
  946. },
  947. hexToAnsi256: {
  948. value: hex => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
  949. enumerable: false
  950. },
  951. ansi256ToAnsi: {
  952. value: code => {
  953. if (code < 8) {
  954. return 30 + code;
  955. }
  956. if (code < 16) {
  957. return 90 + (code - 8);
  958. }
  959. let red;
  960. let green;
  961. let blue;
  962. if (code >= 232) {
  963. red = (((code - 232) * 10) + 8) / 255;
  964. green = red;
  965. blue = red;
  966. } else {
  967. code -= 16;
  968. const remainder = code % 36;
  969. red = Math.floor(code / 36) / 5;
  970. green = Math.floor(remainder / 6) / 5;
  971. blue = (remainder % 6) / 5;
  972. }
  973. const value = Math.max(red, green, blue) * 2;
  974. if (value === 0) {
  975. return 30;
  976. }
  977. let result = 30 + ((Math.round(blue) << 2) | (Math.round(green) << 1) | Math.round(red));
  978. if (value === 2) {
  979. result += 60;
  980. }
  981. return result;
  982. },
  983. enumerable: false
  984. },
  985. rgbToAnsi: {
  986. value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
  987. enumerable: false
  988. },
  989. hexToAnsi: {
  990. value: hex => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
  991. enumerable: false
  992. }
  993. });
  994. return styles;
  995. }
  996. const ansiStyles = assembleStyles();
  997. const ESCAPES = new Set([
  998. '\u001B',
  999. '\u009B',
  1000. ]);
  1001. const END_CODE = 39;
  1002. const ANSI_ESCAPE_BELL = '\u0007';
  1003. const ANSI_CSI = '[';
  1004. const ANSI_OSC = ']';
  1005. const ANSI_SGR_TERMINATOR = 'm';
  1006. const ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
  1007. const wrapAnsiCode = code => `${ESCAPES.values().next().value}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
  1008. const wrapAnsiHyperlink = uri => `${ESCAPES.values().next().value}${ANSI_ESCAPE_LINK}${uri}${ANSI_ESCAPE_BELL}`;
  1009. // Calculate the length of words split on ' ', ignoring
  1010. // the extra characters added by ansi escape codes
  1011. const wordLengths = string => string.split(' ').map(character => stringWidth(character));
  1012. // Wrap a long word across multiple rows
  1013. // Ansi escape codes do not count towards length
  1014. const wrapWord = (rows, word, columns) => {
  1015. const characters = [...word];
  1016. let isInsideEscape = false;
  1017. let isInsideLinkEscape = false;
  1018. let visible = stringWidth(stripAnsi(rows[rows.length - 1]));
  1019. for (const [index, character] of characters.entries()) {
  1020. const characterLength = stringWidth(character);
  1021. if (visible + characterLength <= columns) {
  1022. rows[rows.length - 1] += character;
  1023. } else {
  1024. rows.push(character);
  1025. visible = 0;
  1026. }
  1027. if (ESCAPES.has(character)) {
  1028. isInsideEscape = true;
  1029. isInsideLinkEscape = characters.slice(index + 1).join('').startsWith(ANSI_ESCAPE_LINK);
  1030. }
  1031. if (isInsideEscape) {
  1032. if (isInsideLinkEscape) {
  1033. if (character === ANSI_ESCAPE_BELL) {
  1034. isInsideEscape = false;
  1035. isInsideLinkEscape = false;
  1036. }
  1037. } else if (character === ANSI_SGR_TERMINATOR) {
  1038. isInsideEscape = false;
  1039. }
  1040. continue;
  1041. }
  1042. visible += characterLength;
  1043. if (visible === columns && index < characters.length - 1) {
  1044. rows.push('');
  1045. visible = 0;
  1046. }
  1047. }
  1048. // It's possible that the last row we copy over is only
  1049. // ansi escape characters, handle this edge-case
  1050. if (!visible && rows[rows.length - 1].length > 0 && rows.length > 1) {
  1051. rows[rows.length - 2] += rows.pop();
  1052. }
  1053. };
  1054. // Trims spaces from a string ignoring invisible sequences
  1055. const stringVisibleTrimSpacesRight = string => {
  1056. const words = string.split(' ');
  1057. let last = words.length;
  1058. while (last > 0) {
  1059. if (stringWidth(words[last - 1]) > 0) {
  1060. break;
  1061. }
  1062. last--;
  1063. }
  1064. if (last === words.length) {
  1065. return string;
  1066. }
  1067. return words.slice(0, last).join(' ') + words.slice(last).join('');
  1068. };
  1069. // The wrap-ansi module can be invoked in either 'hard' or 'soft' wrap mode
  1070. //
  1071. // 'hard' will never allow a string to take up more than columns characters
  1072. //
  1073. // 'soft' allows long words to expand past the column length
  1074. const exec = (string, columns, options = {}) => {
  1075. if (options.trim !== false && string.trim() === '') {
  1076. return '';
  1077. }
  1078. let returnValue = '';
  1079. let escapeCode;
  1080. let escapeUrl;
  1081. const lengths = wordLengths(string);
  1082. let rows = [''];
  1083. for (const [index, word] of string.split(' ').entries()) {
  1084. if (options.trim !== false) {
  1085. rows[rows.length - 1] = rows[rows.length - 1].trimStart();
  1086. }
  1087. let rowLength = stringWidth(rows[rows.length - 1]);
  1088. if (index !== 0) {
  1089. if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
  1090. // If we start with a new word but the current row length equals the length of the columns, add a new row
  1091. rows.push('');
  1092. rowLength = 0;
  1093. }
  1094. if (rowLength > 0 || options.trim === false) {
  1095. rows[rows.length - 1] += ' ';
  1096. rowLength++;
  1097. }
  1098. }
  1099. // In 'hard' wrap mode, the length of a line is never allowed to extend past 'columns'
  1100. if (options.hard && lengths[index] > columns) {
  1101. const remainingColumns = (columns - rowLength);
  1102. const breaksStartingThisLine = 1 + Math.floor((lengths[index] - remainingColumns - 1) / columns);
  1103. const breaksStartingNextLine = Math.floor((lengths[index] - 1) / columns);
  1104. if (breaksStartingNextLine < breaksStartingThisLine) {
  1105. rows.push('');
  1106. }
  1107. wrapWord(rows, word, columns);
  1108. continue;
  1109. }
  1110. if (rowLength + lengths[index] > columns && rowLength > 0 && lengths[index] > 0) {
  1111. if (options.wordWrap === false && rowLength < columns) {
  1112. wrapWord(rows, word, columns);
  1113. continue;
  1114. }
  1115. rows.push('');
  1116. }
  1117. if (rowLength + lengths[index] > columns && options.wordWrap === false) {
  1118. wrapWord(rows, word, columns);
  1119. continue;
  1120. }
  1121. rows[rows.length - 1] += word;
  1122. }
  1123. if (options.trim !== false) {
  1124. rows = rows.map(row => stringVisibleTrimSpacesRight(row));
  1125. }
  1126. const pre = [...rows.join('\n')];
  1127. for (const [index, character] of pre.entries()) {
  1128. returnValue += character;
  1129. if (ESCAPES.has(character)) {
  1130. const {groups} = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`).exec(pre.slice(index).join('')) || {groups: {}};
  1131. if (groups.code !== undefined) {
  1132. const code = Number.parseFloat(groups.code);
  1133. escapeCode = code === END_CODE ? undefined : code;
  1134. } else if (groups.uri !== undefined) {
  1135. escapeUrl = groups.uri.length === 0 ? undefined : groups.uri;
  1136. }
  1137. }
  1138. const code = ansiStyles.codes.get(Number(escapeCode));
  1139. if (pre[index + 1] === '\n') {
  1140. if (escapeUrl) {
  1141. returnValue += wrapAnsiHyperlink('');
  1142. }
  1143. if (escapeCode && code) {
  1144. returnValue += wrapAnsiCode(code);
  1145. }
  1146. } else if (character === '\n') {
  1147. if (escapeCode && code) {
  1148. returnValue += wrapAnsiCode(escapeCode);
  1149. }
  1150. if (escapeUrl) {
  1151. returnValue += wrapAnsiHyperlink(escapeUrl);
  1152. }
  1153. }
  1154. }
  1155. return returnValue;
  1156. };
  1157. // For each newline, invoke the method separately
  1158. function wrapAnsi(string, columns, options) {
  1159. return String(string)
  1160. .normalize()
  1161. .replace(/\r\n/g, '\n')
  1162. .split('\n')
  1163. .map(line => exec(line, columns, options))
  1164. .join('\n');
  1165. }
  1166. const originalWrite = Symbol("webpackbarWrite");
  1167. class LogUpdate {
  1168. constructor() {
  1169. this.prevLineCount = 0;
  1170. this.listening = false;
  1171. this.extraLines = "";
  1172. this._onData = this._onData.bind(this);
  1173. this._streams = [process.stdout, process.stderr];
  1174. }
  1175. render(lines) {
  1176. this.listen();
  1177. const wrappedLines = wrapAnsi(lines, this.columns, {
  1178. trim: false,
  1179. hard: true,
  1180. wordWrap: false
  1181. });
  1182. const data = ansiEscapes.eraseLines(this.prevLineCount) + wrappedLines + "\n" + this.extraLines;
  1183. this.write(data);
  1184. const _lines = data.split("\n");
  1185. this.prevLineCount = _lines.length;
  1186. }
  1187. get columns() {
  1188. return (process.stderr.columns || 80) - 2;
  1189. }
  1190. write(data) {
  1191. const stream = process.stderr;
  1192. if (stream.write[originalWrite]) {
  1193. stream.write[originalWrite].call(stream, data, "utf-8");
  1194. } else {
  1195. stream.write(data, "utf-8");
  1196. }
  1197. }
  1198. clear() {
  1199. this.done();
  1200. this.write(ansiEscapes.eraseLines(this.prevLineCount));
  1201. }
  1202. done() {
  1203. this.stopListen();
  1204. this.prevLineCount = 0;
  1205. this.extraLines = "";
  1206. }
  1207. _onData(data) {
  1208. const str = String(data);
  1209. const lines = str.split("\n").length - 1;
  1210. if (lines > 0) {
  1211. this.prevLineCount += lines;
  1212. this.extraLines += data;
  1213. }
  1214. }
  1215. listen() {
  1216. if (this.listening) {
  1217. return;
  1218. }
  1219. for (const stream of this._streams) {
  1220. if (stream.write[originalWrite]) {
  1221. continue;
  1222. }
  1223. const write = (data, ...args) => {
  1224. if (!stream.write[originalWrite]) {
  1225. return stream.write(data, ...args);
  1226. }
  1227. this._onData(data);
  1228. return stream.write[originalWrite].call(stream, data, ...args);
  1229. };
  1230. write[originalWrite] = stream.write;
  1231. stream.write = write;
  1232. }
  1233. this.listening = true;
  1234. }
  1235. stopListen() {
  1236. for (const stream of this._streams) {
  1237. if (stream.write[originalWrite]) {
  1238. stream.write = stream.write[originalWrite];
  1239. }
  1240. }
  1241. this.listening = false;
  1242. }
  1243. }
  1244. const logUpdate = new LogUpdate();
  1245. let lastRender = Date.now();
  1246. class FancyReporter {
  1247. allDone() {
  1248. logUpdate.done();
  1249. }
  1250. done(context) {
  1251. this._renderStates(context.statesArray);
  1252. if (context.hasErrors) {
  1253. logUpdate.done();
  1254. }
  1255. }
  1256. progress(context) {
  1257. if (Date.now() - lastRender > 50) {
  1258. this._renderStates(context.statesArray);
  1259. }
  1260. }
  1261. _renderStates(statesArray) {
  1262. lastRender = Date.now();
  1263. const renderedStates = statesArray.map((c) => this._renderState(c)).join("\n\n");
  1264. logUpdate.render("\n" + renderedStates + "\n");
  1265. }
  1266. _renderState(state) {
  1267. const color = colorize(state.color);
  1268. let line1;
  1269. let line2;
  1270. if (state.progress >= 0 && state.progress < 100) {
  1271. line1 = [
  1272. color(BULLET),
  1273. color(state.name),
  1274. renderBar(state.progress, state.color),
  1275. state.message,
  1276. `(${state.progress || 0}%)`,
  1277. chalk.grey(state.details[0] || ""),
  1278. chalk.grey(state.details[1] || "")
  1279. ].join(" ");
  1280. line2 = state.request ? " " + chalk.grey(ellipsisLeft(formatRequest(state.request), logUpdate.columns)) : "";
  1281. } else {
  1282. let icon = " ";
  1283. if (state.hasErrors) {
  1284. icon = CROSS;
  1285. } else if (state.progress === 100) {
  1286. icon = TICK;
  1287. } else if (state.progress === -1) {
  1288. icon = CIRCLE_OPEN;
  1289. }
  1290. line1 = color(`${icon} ${state.name}`);
  1291. line2 = chalk.grey(" " + state.message);
  1292. }
  1293. return line1 + "\n" + line2;
  1294. }
  1295. }
  1296. class SimpleReporter {
  1297. start(context) {
  1298. consola.info(`Compiling ${context.state.name}`);
  1299. }
  1300. change(context, { shortPath }) {
  1301. consola.debug(`${shortPath} changed.`, `Rebuilding ${context.state.name}`);
  1302. }
  1303. done(context) {
  1304. const { hasError, message, name } = context.state;
  1305. consola[hasError ? "error" : "success"](`${name}: ${message}`);
  1306. }
  1307. }
  1308. const DB = {
  1309. loader: {
  1310. get: (loader) => startCase(loader)
  1311. },
  1312. ext: {
  1313. get: (ext) => `${ext} files`,
  1314. vue: "Vue Single File components",
  1315. js: "JavaScript files",
  1316. sass: "SASS files",
  1317. scss: "SASS files",
  1318. unknown: "Unknown files"
  1319. }
  1320. };
  1321. function getDescription(category, keyword) {
  1322. if (!DB[category]) {
  1323. return startCase(keyword);
  1324. }
  1325. if (DB[category][keyword]) {
  1326. return DB[category][keyword];
  1327. }
  1328. if (DB[category].get) {
  1329. return DB[category].get(keyword);
  1330. }
  1331. return "-";
  1332. }
  1333. function formatStats(allStats) {
  1334. const lines = [];
  1335. Object.keys(allStats).forEach((category) => {
  1336. const stats = allStats[category];
  1337. lines.push(`> Stats by ${chalk.bold(startCase(category))}`);
  1338. let totalRequests = 0;
  1339. const totalTime = [0, 0];
  1340. const data = [
  1341. [startCase(category), "Requests", "Time", "Time/Request", "Description"]
  1342. ];
  1343. Object.keys(stats).forEach((item) => {
  1344. const stat = stats[item];
  1345. totalRequests += stat.count || 0;
  1346. const description = getDescription(category, item);
  1347. totalTime[0] += stat.time[0];
  1348. totalTime[1] += stat.time[1];
  1349. const avgTime = [stat.time[0] / stat.count, stat.time[1] / stat.count];
  1350. data.push([
  1351. item,
  1352. stat.count || "-",
  1353. prettyTime(stat.time),
  1354. prettyTime(avgTime),
  1355. description
  1356. ]);
  1357. });
  1358. data.push(["Total", totalRequests, prettyTime(totalTime), "", ""]);
  1359. lines.push(createTable(data));
  1360. });
  1361. return `${lines.join("\n\n")}
  1362. `;
  1363. }
  1364. class Profiler {
  1365. constructor() {
  1366. this.requests = [];
  1367. }
  1368. onRequest(request) {
  1369. if (!request) {
  1370. return;
  1371. }
  1372. if (this.requests.length) {
  1373. const lastReq = this.requests[this.requests.length - 1];
  1374. if (lastReq.start) {
  1375. lastReq.time = process.hrtime(lastReq.start);
  1376. delete lastReq.start;
  1377. }
  1378. }
  1379. if (!request.file || !request.loaders.length) {
  1380. return;
  1381. }
  1382. this.requests.push({
  1383. request,
  1384. start: process.hrtime()
  1385. });
  1386. }
  1387. getStats() {
  1388. const loaderStats = {};
  1389. const extStats = {};
  1390. const getStat = (stats, name) => {
  1391. if (!stats[name]) {
  1392. stats[name] = {
  1393. count: 0,
  1394. time: [0, 0]
  1395. };
  1396. }
  1397. return stats[name];
  1398. };
  1399. const addToStat = (stats, name, count, time) => {
  1400. const stat = getStat(stats, name);
  1401. stat.count += count;
  1402. stat.time[0] += time[0];
  1403. stat.time[1] += time[1];
  1404. };
  1405. this.requests.forEach(({ request, time = [0, 0] }) => {
  1406. request.loaders.forEach((loader) => {
  1407. addToStat(loaderStats, loader, 1, time);
  1408. });
  1409. const ext = request.file && path.extname(request.file).substr(1);
  1410. addToStat(extStats, ext && ext.length ? ext : "unknown", 1, time);
  1411. });
  1412. return {
  1413. ext: extStats,
  1414. loader: loaderStats
  1415. };
  1416. }
  1417. getFormattedStats() {
  1418. return formatStats(this.getStats());
  1419. }
  1420. }
  1421. class ProfileReporter {
  1422. progress(context) {
  1423. if (!context.state.profiler) {
  1424. context.state.profiler = new Profiler();
  1425. }
  1426. context.state.profiler.onRequest(context.state.request);
  1427. }
  1428. done(context) {
  1429. if (context.state.profiler) {
  1430. context.state.profile = context.state.profiler.getFormattedStats();
  1431. delete context.state.profiler;
  1432. }
  1433. }
  1434. allDone(context) {
  1435. let str = "";
  1436. for (const state of context.statesArray) {
  1437. const color = colorize(state.color);
  1438. if (state.profile) {
  1439. str += color(`
  1440. Profile results for ${chalk.bold(state.name)}
  1441. `) + `
  1442. ${state.profile}
  1443. `;
  1444. delete state.profile;
  1445. }
  1446. }
  1447. process.stderr.write(str);
  1448. }
  1449. }
  1450. class StatsReporter {
  1451. constructor(options) {
  1452. this.options = Object.assign({
  1453. chunks: false,
  1454. children: false,
  1455. modules: false,
  1456. colors: true,
  1457. warnings: true,
  1458. errors: true
  1459. }, options);
  1460. }
  1461. done(context, { stats }) {
  1462. const str = stats.toString(this.options);
  1463. if (context.hasErrors) {
  1464. process.stderr.write("\n" + str + "\n");
  1465. } else {
  1466. context.state.statsString = str;
  1467. }
  1468. }
  1469. allDone(context) {
  1470. let str = "";
  1471. for (const state of context.statesArray) {
  1472. if (state.statsString) {
  1473. str += "\n" + state.statsString + "\n";
  1474. delete state.statsString;
  1475. }
  1476. }
  1477. process.stderr.write(str);
  1478. }
  1479. }
  1480. const reporters = {
  1481. __proto__: null,
  1482. fancy: FancyReporter,
  1483. basic: SimpleReporter,
  1484. profile: ProfileReporter,
  1485. stats: StatsReporter
  1486. };
  1487. const DEFAULTS = {
  1488. name: "webpack",
  1489. color: "green",
  1490. reporters: isMinimal ? ["basic"] : ["fancy"],
  1491. reporter: null
  1492. };
  1493. const DEFAULT_STATE = {
  1494. start: null,
  1495. progress: -1,
  1496. done: false,
  1497. message: "",
  1498. details: [],
  1499. request: null,
  1500. hasErrors: false
  1501. };
  1502. const globalStates = {};
  1503. class WebpackBarPlugin extends Webpack.ProgressPlugin {
  1504. constructor(options) {
  1505. super({ activeModules: true });
  1506. this.options = Object.assign({}, DEFAULTS, options);
  1507. this.handler = (percent, message, ...details) => {
  1508. this.updateProgress(percent, message, details);
  1509. };
  1510. const _reporters = Array.from(this.options.reporters || []).concat(this.options.reporter).filter(Boolean).map((reporter) => {
  1511. if (Array.isArray(reporter)) {
  1512. return { reporter: reporter[0], options: reporter[1] };
  1513. }
  1514. if (typeof reporter === "string") {
  1515. return { reporter };
  1516. }
  1517. return { reporter };
  1518. });
  1519. this.reporters = _reporters.map(({ reporter, options: options2 = {} }) => {
  1520. if (typeof reporter === "string") {
  1521. if (this.options[reporter] === false) {
  1522. return void 0;
  1523. }
  1524. options2 = { ...this.options[reporter], ...options2 };
  1525. reporter = reporters[reporter] || require(reporter);
  1526. }
  1527. if (typeof reporter === "function") {
  1528. try {
  1529. reporter = new reporter(options2);
  1530. } catch (err) {
  1531. reporter = reporter(options2);
  1532. }
  1533. }
  1534. return reporter;
  1535. }).filter(Boolean);
  1536. }
  1537. callReporters(fn, payload = {}) {
  1538. for (const reporter of this.reporters) {
  1539. if (typeof reporter[fn] === "function") {
  1540. try {
  1541. reporter[fn](this, payload);
  1542. } catch (e) {
  1543. process.stdout.write(e.stack + "\n");
  1544. }
  1545. }
  1546. }
  1547. }
  1548. get hasRunning() {
  1549. return objectValues(this.states).some((state) => !state.done);
  1550. }
  1551. get hasErrors() {
  1552. return objectValues(this.states).some((state) => state.hasErrors);
  1553. }
  1554. get statesArray() {
  1555. return objectValues(this.states).sort((s1, s2) => s1.name.localeCompare(s2.name));
  1556. }
  1557. get states() {
  1558. return globalStates;
  1559. }
  1560. get state() {
  1561. return globalStates[this.options.name];
  1562. }
  1563. _ensureState() {
  1564. if (!this.states[this.options.name]) {
  1565. this.states[this.options.name] = {
  1566. ...DEFAULT_STATE,
  1567. color: this.options.color,
  1568. name: startCase(this.options.name)
  1569. };
  1570. }
  1571. }
  1572. apply(compiler) {
  1573. if (compiler.webpackbar) {
  1574. return;
  1575. }
  1576. compiler.webpackbar = this;
  1577. super.apply(compiler);
  1578. hook(compiler, "afterPlugins", () => {
  1579. this._ensureState();
  1580. });
  1581. hook(compiler, "compile", () => {
  1582. this._ensureState();
  1583. Object.assign(this.state, {
  1584. ...DEFAULT_STATE,
  1585. start: process.hrtime()
  1586. });
  1587. this.callReporters("start");
  1588. });
  1589. hook(compiler, "invalid", (fileName, changeTime) => {
  1590. this._ensureState();
  1591. this.callReporters("change", {
  1592. path: fileName,
  1593. shortPath: shortenPath(fileName),
  1594. time: changeTime
  1595. });
  1596. });
  1597. hook(compiler, "done", (stats) => {
  1598. this._ensureState();
  1599. if (this.state.done) {
  1600. return;
  1601. }
  1602. const hasErrors = stats.hasErrors();
  1603. const status = hasErrors ? "with some errors" : "successfully";
  1604. const time = this.state.start ? " in " + prettyTime(process.hrtime(this.state.start), 2) : "";
  1605. Object.assign(this.state, {
  1606. ...DEFAULT_STATE,
  1607. progress: 100,
  1608. done: true,
  1609. message: `Compiled ${status}${time}`,
  1610. hasErrors
  1611. });
  1612. this.callReporters("progress");
  1613. this.callReporters("done", { stats });
  1614. if (!this.hasRunning) {
  1615. this.callReporters("beforeAllDone");
  1616. this.callReporters("allDone");
  1617. this.callReporters("afterAllDone");
  1618. }
  1619. });
  1620. }
  1621. updateProgress(percent = 0, message = "", details = []) {
  1622. const progress = Math.floor(percent * 100);
  1623. const activeModule = details.pop();
  1624. Object.assign(this.state, {
  1625. progress,
  1626. message: message || "",
  1627. details,
  1628. request: parseRequest(activeModule)
  1629. });
  1630. this.callReporters("progress");
  1631. }
  1632. }
  1633. export { WebpackBarPlugin as default };