11cb0ef41Sopenharmony_ci// this is called when an ERESOLVE error is caught in the exit-handler, 21cb0ef41Sopenharmony_ci// or when there's a log.warn('eresolve', msg, explanation), to turn it 31cb0ef41Sopenharmony_ci// into a human-intelligible explanation of what's wrong and how to fix. 41cb0ef41Sopenharmony_ciconst { explainEdge, explainNode, printNode } = require('./explain-dep.js') 51cb0ef41Sopenharmony_ci 61cb0ef41Sopenharmony_ci// expl is an explanation object that comes from Arborist. It looks like: 71cb0ef41Sopenharmony_ci// Depth is how far we want to want to descend into the object making a report. 81cb0ef41Sopenharmony_ci// The full report (ie, depth=Infinity) is always written to the cache folder 91cb0ef41Sopenharmony_ci// at ${cache}/eresolve-report.txt along with full json. 101cb0ef41Sopenharmony_ciconst explain = (expl, chalk, depth) => { 111cb0ef41Sopenharmony_ci const { edge, dep, current, peerConflict, currentEdge } = expl 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ci const out = [] 141cb0ef41Sopenharmony_ci const whileInstalling = dep && dep.whileInstalling || 151cb0ef41Sopenharmony_ci current && current.whileInstalling || 161cb0ef41Sopenharmony_ci edge && edge.from && edge.from.whileInstalling 171cb0ef41Sopenharmony_ci if (whileInstalling) { 181cb0ef41Sopenharmony_ci out.push('While resolving: ' + printNode(whileInstalling, chalk)) 191cb0ef41Sopenharmony_ci } 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ci // it "should" be impossible for an ERESOLVE explanation to lack both 221cb0ef41Sopenharmony_ci // current and currentEdge, but better to have a less helpful error 231cb0ef41Sopenharmony_ci // than a crashing failure. 241cb0ef41Sopenharmony_ci if (current) { 251cb0ef41Sopenharmony_ci out.push('Found: ' + explainNode(current, depth, chalk)) 261cb0ef41Sopenharmony_ci } else if (peerConflict && peerConflict.current) { 271cb0ef41Sopenharmony_ci out.push('Found: ' + explainNode(peerConflict.current, depth, chalk)) 281cb0ef41Sopenharmony_ci } else if (currentEdge) { 291cb0ef41Sopenharmony_ci out.push('Found: ' + explainEdge(currentEdge, depth, chalk)) 301cb0ef41Sopenharmony_ci } else /* istanbul ignore else - should always have one */ if (edge) { 311cb0ef41Sopenharmony_ci out.push('Found: ' + explainEdge(edge, depth, chalk)) 321cb0ef41Sopenharmony_ci } 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci out.push('\nCould not resolve dependency:\n' + 351cb0ef41Sopenharmony_ci explainEdge(edge, depth, chalk)) 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_ci if (peerConflict) { 381cb0ef41Sopenharmony_ci const heading = '\nConflicting peer dependency:' 391cb0ef41Sopenharmony_ci const pc = explainNode(peerConflict.peer, depth, chalk) 401cb0ef41Sopenharmony_ci out.push(heading + ' ' + pc) 411cb0ef41Sopenharmony_ci } 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ci return out.join('\n') 441cb0ef41Sopenharmony_ci} 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci// generate a full verbose report and tell the user how to fix it 471cb0ef41Sopenharmony_ciconst report = (expl, chalk, noColorChalk) => { 481cb0ef41Sopenharmony_ci const flags = [ 491cb0ef41Sopenharmony_ci expl.strictPeerDeps ? '--no-strict-peer-deps' : '', 501cb0ef41Sopenharmony_ci '--force', 511cb0ef41Sopenharmony_ci '--legacy-peer-deps', 521cb0ef41Sopenharmony_ci ].filter(Boolean) 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci const or = (arr) => arr.length <= 2 551cb0ef41Sopenharmony_ci ? arr.join(' or ') : 561cb0ef41Sopenharmony_ci arr.map((v, i, l) => i + 1 === l.length ? `or ${v}` : v).join(', ') 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ci const fix = `Fix the upstream dependency conflict, or retry 591cb0ef41Sopenharmony_cithis command with ${or(flags)} 601cb0ef41Sopenharmony_cito accept an incorrect (and potentially broken) dependency resolution.` 611cb0ef41Sopenharmony_ci 621cb0ef41Sopenharmony_ci return { 631cb0ef41Sopenharmony_ci explanation: `${explain(expl, chalk, 4)}\n\n${fix}`, 641cb0ef41Sopenharmony_ci file: `# npm resolution error report\n\n${explain(expl, noColorChalk, Infinity)}\n\n${fix}`, 651cb0ef41Sopenharmony_ci } 661cb0ef41Sopenharmony_ci} 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_cimodule.exports = { 691cb0ef41Sopenharmony_ci explain, 701cb0ef41Sopenharmony_ci report, 711cb0ef41Sopenharmony_ci} 72