11cb0ef41Sopenharmony_ciconst { format } = require('util')
21cb0ef41Sopenharmony_ciconst { resolve } = require('path')
31cb0ef41Sopenharmony_ciconst nameValidator = require('validate-npm-package-name')
41cb0ef41Sopenharmony_ciconst replaceInfo = require('./replace-info.js')
51cb0ef41Sopenharmony_ciconst { report } = require('./explain-eresolve.js')
61cb0ef41Sopenharmony_ciconst log = require('./log-shim')
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ciconst messageText = msg => msg.map(line => line.slice(1).join(' ')).join('\n')
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ciconst jsonError = (er, npm, { summary, detail }) => {
111cb0ef41Sopenharmony_ci  if (npm?.config.loaded && npm.config.get('json')) {
121cb0ef41Sopenharmony_ci    return {
131cb0ef41Sopenharmony_ci      error: {
141cb0ef41Sopenharmony_ci        code: er.code,
151cb0ef41Sopenharmony_ci        summary: messageText(summary),
161cb0ef41Sopenharmony_ci        detail: messageText(detail),
171cb0ef41Sopenharmony_ci      },
181cb0ef41Sopenharmony_ci    }
191cb0ef41Sopenharmony_ci  }
201cb0ef41Sopenharmony_ci}
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ciconst errorMessage = (er, npm) => {
231cb0ef41Sopenharmony_ci  const short = []
241cb0ef41Sopenharmony_ci  const detail = []
251cb0ef41Sopenharmony_ci  const files = []
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ci  if (er.message) {
281cb0ef41Sopenharmony_ci    er.message = replaceInfo(er.message)
291cb0ef41Sopenharmony_ci  }
301cb0ef41Sopenharmony_ci  if (er.stack) {
311cb0ef41Sopenharmony_ci    er.stack = replaceInfo(er.stack)
321cb0ef41Sopenharmony_ci  }
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci  switch (er.code) {
351cb0ef41Sopenharmony_ci    case 'ERESOLVE': {
361cb0ef41Sopenharmony_ci      short.push(['ERESOLVE', er.message])
371cb0ef41Sopenharmony_ci      detail.push(['', ''])
381cb0ef41Sopenharmony_ci      // XXX(display): error messages are logged so we use the logColor since that is based
391cb0ef41Sopenharmony_ci      // on stderr. This should be handled solely by the display layer so it could also be
401cb0ef41Sopenharmony_ci      // printed to stdout if necessary.
411cb0ef41Sopenharmony_ci      const { explanation, file } = report(er, npm.logChalk, npm.noColorChalk)
421cb0ef41Sopenharmony_ci      detail.push(['', explanation])
431cb0ef41Sopenharmony_ci      files.push(['eresolve-report.txt', file])
441cb0ef41Sopenharmony_ci      break
451cb0ef41Sopenharmony_ci    }
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci    case 'ENOLOCK': {
481cb0ef41Sopenharmony_ci      const cmd = npm.command || ''
491cb0ef41Sopenharmony_ci      short.push([cmd, 'This command requires an existing lockfile.'])
501cb0ef41Sopenharmony_ci      detail.push([cmd, 'Try creating one first with: npm i --package-lock-only'])
511cb0ef41Sopenharmony_ci      detail.push([cmd, `Original error: ${er.message}`])
521cb0ef41Sopenharmony_ci      break
531cb0ef41Sopenharmony_ci    }
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci    case 'ENOAUDIT':
561cb0ef41Sopenharmony_ci      short.push(['audit', er.message])
571cb0ef41Sopenharmony_ci      break
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ci    case 'ECONNREFUSED':
601cb0ef41Sopenharmony_ci      short.push(['', er])
611cb0ef41Sopenharmony_ci      detail.push([
621cb0ef41Sopenharmony_ci        '',
631cb0ef41Sopenharmony_ci        [
641cb0ef41Sopenharmony_ci          '\nIf you are behind a proxy, please make sure that the',
651cb0ef41Sopenharmony_ci          "'proxy' config is set properly.  See: 'npm help config'",
661cb0ef41Sopenharmony_ci        ].join('\n'),
671cb0ef41Sopenharmony_ci      ])
681cb0ef41Sopenharmony_ci      break
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ci    case 'EACCES':
711cb0ef41Sopenharmony_ci    case 'EPERM': {
721cb0ef41Sopenharmony_ci      const isCachePath =
731cb0ef41Sopenharmony_ci        typeof er.path === 'string' &&
741cb0ef41Sopenharmony_ci        npm.config.loaded &&
751cb0ef41Sopenharmony_ci        er.path.startsWith(npm.config.get('cache'))
761cb0ef41Sopenharmony_ci      const isCacheDest =
771cb0ef41Sopenharmony_ci        typeof er.dest === 'string' &&
781cb0ef41Sopenharmony_ci        npm.config.loaded &&
791cb0ef41Sopenharmony_ci        er.dest.startsWith(npm.config.get('cache'))
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci      const { isWindows } = require('./is-windows.js')
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ci      if (!isWindows && (isCachePath || isCacheDest)) {
841cb0ef41Sopenharmony_ci        // user probably doesn't need this, but still add it to the debug log
851cb0ef41Sopenharmony_ci        log.verbose(er.stack)
861cb0ef41Sopenharmony_ci        short.push([
871cb0ef41Sopenharmony_ci          '',
881cb0ef41Sopenharmony_ci          [
891cb0ef41Sopenharmony_ci            '',
901cb0ef41Sopenharmony_ci            'Your cache folder contains root-owned files, due to a bug in',
911cb0ef41Sopenharmony_ci            'previous versions of npm which has since been addressed.',
921cb0ef41Sopenharmony_ci            '',
931cb0ef41Sopenharmony_ci            'To permanently fix this problem, please run:',
941cb0ef41Sopenharmony_ci            `  sudo chown -R ${process.getuid()}:${process.getgid()} ${JSON.stringify(
951cb0ef41Sopenharmony_ci              npm.config.get('cache')
961cb0ef41Sopenharmony_ci            )}`,
971cb0ef41Sopenharmony_ci          ].join('\n'),
981cb0ef41Sopenharmony_ci        ])
991cb0ef41Sopenharmony_ci      } else {
1001cb0ef41Sopenharmony_ci        short.push(['', er])
1011cb0ef41Sopenharmony_ci        detail.push([
1021cb0ef41Sopenharmony_ci          '',
1031cb0ef41Sopenharmony_ci          [
1041cb0ef41Sopenharmony_ci            '\nThe operation was rejected by your operating system.',
1051cb0ef41Sopenharmony_ci            isWindows
1061cb0ef41Sopenharmony_ci              /* eslint-disable-next-line max-len */
1071cb0ef41Sopenharmony_ci              ? "It's possible that the file was already in use (by a text editor or antivirus),\n" +
1081cb0ef41Sopenharmony_ci                'or that you lack permissions to access it.'
1091cb0ef41Sopenharmony_ci              /* eslint-disable-next-line max-len */
1101cb0ef41Sopenharmony_ci              : 'It is likely you do not have the permissions to access this file as the current user',
1111cb0ef41Sopenharmony_ci            '\nIf you believe this might be a permissions issue, please double-check the',
1121cb0ef41Sopenharmony_ci            'permissions of the file and its containing directories, or try running',
1131cb0ef41Sopenharmony_ci            'the command again as root/Administrator.',
1141cb0ef41Sopenharmony_ci          ].join('\n'),
1151cb0ef41Sopenharmony_ci        ])
1161cb0ef41Sopenharmony_ci      }
1171cb0ef41Sopenharmony_ci      break
1181cb0ef41Sopenharmony_ci    }
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci    case 'ENOGIT':
1211cb0ef41Sopenharmony_ci      short.push(['', er.message])
1221cb0ef41Sopenharmony_ci      detail.push([
1231cb0ef41Sopenharmony_ci        '',
1241cb0ef41Sopenharmony_ci        ['', 'Failed using git.', 'Please check if you have git installed and in your PATH.'].join(
1251cb0ef41Sopenharmony_ci          '\n'
1261cb0ef41Sopenharmony_ci        ),
1271cb0ef41Sopenharmony_ci      ])
1281cb0ef41Sopenharmony_ci      break
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_ci    case 'EJSONPARSE':
1311cb0ef41Sopenharmony_ci      // Check whether we ran into a conflict in our own package.json
1321cb0ef41Sopenharmony_ci      if (er.path === resolve(npm.prefix, 'package.json')) {
1331cb0ef41Sopenharmony_ci        const { isDiff } = require('parse-conflict-json')
1341cb0ef41Sopenharmony_ci        const txt = require('fs').readFileSync(er.path, 'utf8').replace(/\r\n/g, '\n')
1351cb0ef41Sopenharmony_ci        if (isDiff(txt)) {
1361cb0ef41Sopenharmony_ci          detail.push([
1371cb0ef41Sopenharmony_ci            '',
1381cb0ef41Sopenharmony_ci            [
1391cb0ef41Sopenharmony_ci              'Merge conflict detected in your package.json.',
1401cb0ef41Sopenharmony_ci              '',
1411cb0ef41Sopenharmony_ci              'Please resolve the package.json conflict and retry.',
1421cb0ef41Sopenharmony_ci            ].join('\n'),
1431cb0ef41Sopenharmony_ci          ])
1441cb0ef41Sopenharmony_ci          break
1451cb0ef41Sopenharmony_ci        }
1461cb0ef41Sopenharmony_ci      }
1471cb0ef41Sopenharmony_ci      short.push(['JSON.parse', er.message])
1481cb0ef41Sopenharmony_ci      detail.push([
1491cb0ef41Sopenharmony_ci        'JSON.parse',
1501cb0ef41Sopenharmony_ci        [
1511cb0ef41Sopenharmony_ci          'Failed to parse JSON data.',
1521cb0ef41Sopenharmony_ci          'Note: package.json must be actual JSON, not just JavaScript.',
1531cb0ef41Sopenharmony_ci        ].join('\n'),
1541cb0ef41Sopenharmony_ci      ])
1551cb0ef41Sopenharmony_ci      break
1561cb0ef41Sopenharmony_ci
1571cb0ef41Sopenharmony_ci    case 'EOTP':
1581cb0ef41Sopenharmony_ci    case 'E401':
1591cb0ef41Sopenharmony_ci      // E401 is for places where we accidentally neglect OTP stuff
1601cb0ef41Sopenharmony_ci      if (er.code === 'EOTP' || /one-time pass/.test(er.message)) {
1611cb0ef41Sopenharmony_ci        short.push(['', 'This operation requires a one-time password from your authenticator.'])
1621cb0ef41Sopenharmony_ci        detail.push([
1631cb0ef41Sopenharmony_ci          '',
1641cb0ef41Sopenharmony_ci          [
1651cb0ef41Sopenharmony_ci            'You can provide a one-time password by passing --otp=<code> to the command you ran.',
1661cb0ef41Sopenharmony_ci            'If you already provided a one-time password then it is likely that you either typoed',
1671cb0ef41Sopenharmony_ci            'it, or it timed out. Please try again.',
1681cb0ef41Sopenharmony_ci          ].join('\n'),
1691cb0ef41Sopenharmony_ci        ])
1701cb0ef41Sopenharmony_ci      } else {
1711cb0ef41Sopenharmony_ci        // npm ERR! code E401
1721cb0ef41Sopenharmony_ci        // npm ERR! Unable to authenticate, need: Basic
1731cb0ef41Sopenharmony_ci        const auth =
1741cb0ef41Sopenharmony_ci          !er.headers || !er.headers['www-authenticate']
1751cb0ef41Sopenharmony_ci            ? []
1761cb0ef41Sopenharmony_ci            : er.headers['www-authenticate'].map(au => au.split(/[,\s]+/))[0]
1771cb0ef41Sopenharmony_ci
1781cb0ef41Sopenharmony_ci        if (auth.includes('Bearer')) {
1791cb0ef41Sopenharmony_ci          short.push([
1801cb0ef41Sopenharmony_ci            '',
1811cb0ef41Sopenharmony_ci            'Unable to authenticate, your authentication token seems to be invalid.',
1821cb0ef41Sopenharmony_ci          ])
1831cb0ef41Sopenharmony_ci          detail.push([
1841cb0ef41Sopenharmony_ci            '',
1851cb0ef41Sopenharmony_ci            ['To correct this please try logging in again with:', '    npm login'].join('\n'),
1861cb0ef41Sopenharmony_ci          ])
1871cb0ef41Sopenharmony_ci        } else if (auth.includes('Basic')) {
1881cb0ef41Sopenharmony_ci          short.push(['', 'Incorrect or missing password.'])
1891cb0ef41Sopenharmony_ci          detail.push([
1901cb0ef41Sopenharmony_ci            '',
1911cb0ef41Sopenharmony_ci            [
1921cb0ef41Sopenharmony_ci              'If you were trying to login, change your password, create an',
1931cb0ef41Sopenharmony_ci              'authentication token or enable two-factor authentication then',
1941cb0ef41Sopenharmony_ci              'that means you likely typed your password in incorrectly.',
1951cb0ef41Sopenharmony_ci              'Please try again, or recover your password at:',
1961cb0ef41Sopenharmony_ci              '    https://www.npmjs.com/forgot',
1971cb0ef41Sopenharmony_ci              '',
1981cb0ef41Sopenharmony_ci              'If you were doing some other operation then your saved credentials are',
1991cb0ef41Sopenharmony_ci              'probably out of date. To correct this please try logging in again with:',
2001cb0ef41Sopenharmony_ci              '    npm login',
2011cb0ef41Sopenharmony_ci            ].join('\n'),
2021cb0ef41Sopenharmony_ci          ])
2031cb0ef41Sopenharmony_ci        } else {
2041cb0ef41Sopenharmony_ci          short.push(['', er.message || er])
2051cb0ef41Sopenharmony_ci        }
2061cb0ef41Sopenharmony_ci      }
2071cb0ef41Sopenharmony_ci      break
2081cb0ef41Sopenharmony_ci
2091cb0ef41Sopenharmony_ci    case 'E404':
2101cb0ef41Sopenharmony_ci      // There's no need to have 404 in the message as well.
2111cb0ef41Sopenharmony_ci      short.push(['404', er.message.replace(/^404\s+/, '')])
2121cb0ef41Sopenharmony_ci      if (er.pkgid && er.pkgid !== '-') {
2131cb0ef41Sopenharmony_ci        const pkg = er.pkgid.replace(/(?!^)@.*$/, '')
2141cb0ef41Sopenharmony_ci
2151cb0ef41Sopenharmony_ci        detail.push(['404', ''])
2161cb0ef41Sopenharmony_ci        detail.push(['404', '', `'${replaceInfo(er.pkgid)}' is not in this registry.`])
2171cb0ef41Sopenharmony_ci
2181cb0ef41Sopenharmony_ci        const valResult = nameValidator(pkg)
2191cb0ef41Sopenharmony_ci
2201cb0ef41Sopenharmony_ci        if (!valResult.validForNewPackages) {
2211cb0ef41Sopenharmony_ci          detail.push(['404', 'This package name is not valid, because', ''])
2221cb0ef41Sopenharmony_ci
2231cb0ef41Sopenharmony_ci          const errorsArray = [...(valResult.errors || []), ...(valResult.warnings || [])]
2241cb0ef41Sopenharmony_ci          errorsArray.forEach((item, idx) => detail.push(['404', ' ' + (idx + 1) + '. ' + item]))
2251cb0ef41Sopenharmony_ci        }
2261cb0ef41Sopenharmony_ci
2271cb0ef41Sopenharmony_ci        detail.push(['404', '\nNote that you can also install from a'])
2281cb0ef41Sopenharmony_ci        detail.push(['404', 'tarball, folder, http url, or git url.'])
2291cb0ef41Sopenharmony_ci      }
2301cb0ef41Sopenharmony_ci      break
2311cb0ef41Sopenharmony_ci
2321cb0ef41Sopenharmony_ci    case 'EPUBLISHCONFLICT':
2331cb0ef41Sopenharmony_ci      short.push(['publish fail', 'Cannot publish over existing version.'])
2341cb0ef41Sopenharmony_ci      detail.push(['publish fail', "Update the 'version' field in package.json and try again."])
2351cb0ef41Sopenharmony_ci      detail.push(['publish fail', ''])
2361cb0ef41Sopenharmony_ci      detail.push(['publish fail', 'To automatically increment version numbers, see:'])
2371cb0ef41Sopenharmony_ci      detail.push(['publish fail', '    npm help version'])
2381cb0ef41Sopenharmony_ci      break
2391cb0ef41Sopenharmony_ci
2401cb0ef41Sopenharmony_ci    case 'EISGIT':
2411cb0ef41Sopenharmony_ci      short.push(['git', er.message])
2421cb0ef41Sopenharmony_ci      short.push(['git', '    ' + er.path])
2431cb0ef41Sopenharmony_ci      detail.push([
2441cb0ef41Sopenharmony_ci        'git',
2451cb0ef41Sopenharmony_ci        ['Refusing to remove it. Update manually,', 'or move it out of the way first.'].join('\n'),
2461cb0ef41Sopenharmony_ci      ])
2471cb0ef41Sopenharmony_ci      break
2481cb0ef41Sopenharmony_ci
2491cb0ef41Sopenharmony_ci    case 'EBADPLATFORM': {
2501cb0ef41Sopenharmony_ci      const actual = er.current
2511cb0ef41Sopenharmony_ci      const expected = { ...er.required }
2521cb0ef41Sopenharmony_ci      const checkedKeys = []
2531cb0ef41Sopenharmony_ci      for (const key in expected) {
2541cb0ef41Sopenharmony_ci        if (Array.isArray(expected[key]) && expected[key].length > 0) {
2551cb0ef41Sopenharmony_ci          expected[key] = expected[key].join(',')
2561cb0ef41Sopenharmony_ci          checkedKeys.push(key)
2571cb0ef41Sopenharmony_ci        } else if (expected[key] === undefined ||
2581cb0ef41Sopenharmony_ci            Array.isArray(expected[key]) && expected[key].length === 0) {
2591cb0ef41Sopenharmony_ci          delete expected[key]
2601cb0ef41Sopenharmony_ci          delete actual[key]
2611cb0ef41Sopenharmony_ci        } else {
2621cb0ef41Sopenharmony_ci          checkedKeys.push(key)
2631cb0ef41Sopenharmony_ci        }
2641cb0ef41Sopenharmony_ci      }
2651cb0ef41Sopenharmony_ci
2661cb0ef41Sopenharmony_ci      const longestKey = Math.max(...checkedKeys.map((key) => key.length))
2671cb0ef41Sopenharmony_ci      const detailEntry = []
2681cb0ef41Sopenharmony_ci      for (const key of checkedKeys) {
2691cb0ef41Sopenharmony_ci        const padding = key.length === longestKey
2701cb0ef41Sopenharmony_ci          ? 1
2711cb0ef41Sopenharmony_ci          : 1 + (longestKey - key.length)
2721cb0ef41Sopenharmony_ci
2731cb0ef41Sopenharmony_ci        // padding + 1 because 'actual' is longer than 'valid'
2741cb0ef41Sopenharmony_ci        detailEntry.push(`Valid ${key}:${' '.repeat(padding + 1)}${expected[key]}`)
2751cb0ef41Sopenharmony_ci        detailEntry.push(`Actual ${key}:${' '.repeat(padding)}${actual[key]}`)
2761cb0ef41Sopenharmony_ci      }
2771cb0ef41Sopenharmony_ci
2781cb0ef41Sopenharmony_ci      short.push([
2791cb0ef41Sopenharmony_ci        'notsup',
2801cb0ef41Sopenharmony_ci        [
2811cb0ef41Sopenharmony_ci          format(
2821cb0ef41Sopenharmony_ci            'Unsupported platform for %s: wanted %j (current: %j)',
2831cb0ef41Sopenharmony_ci            er.pkgid,
2841cb0ef41Sopenharmony_ci            expected,
2851cb0ef41Sopenharmony_ci            actual
2861cb0ef41Sopenharmony_ci          ),
2871cb0ef41Sopenharmony_ci        ].join('\n'),
2881cb0ef41Sopenharmony_ci      ])
2891cb0ef41Sopenharmony_ci      detail.push([
2901cb0ef41Sopenharmony_ci        'notsup',
2911cb0ef41Sopenharmony_ci        detailEntry.join('\n'),
2921cb0ef41Sopenharmony_ci      ])
2931cb0ef41Sopenharmony_ci      break
2941cb0ef41Sopenharmony_ci    }
2951cb0ef41Sopenharmony_ci
2961cb0ef41Sopenharmony_ci    case 'EEXIST':
2971cb0ef41Sopenharmony_ci      short.push(['', er.message])
2981cb0ef41Sopenharmony_ci      short.push(['', 'File exists: ' + (er.dest || er.path)])
2991cb0ef41Sopenharmony_ci      detail.push(['', 'Remove the existing file and try again, or run npm'])
3001cb0ef41Sopenharmony_ci      detail.push(['', 'with --force to overwrite files recklessly.'])
3011cb0ef41Sopenharmony_ci      break
3021cb0ef41Sopenharmony_ci
3031cb0ef41Sopenharmony_ci    case 'ENEEDAUTH':
3041cb0ef41Sopenharmony_ci      short.push(['need auth', er.message])
3051cb0ef41Sopenharmony_ci      detail.push(['need auth', 'You need to authorize this machine using `npm adduser`'])
3061cb0ef41Sopenharmony_ci      break
3071cb0ef41Sopenharmony_ci
3081cb0ef41Sopenharmony_ci    case 'ECONNRESET':
3091cb0ef41Sopenharmony_ci    case 'ENOTFOUND':
3101cb0ef41Sopenharmony_ci    case 'ETIMEDOUT':
3111cb0ef41Sopenharmony_ci    case 'ERR_SOCKET_TIMEOUT':
3121cb0ef41Sopenharmony_ci    case 'EAI_FAIL':
3131cb0ef41Sopenharmony_ci      short.push(['network', er.message])
3141cb0ef41Sopenharmony_ci      detail.push([
3151cb0ef41Sopenharmony_ci        'network',
3161cb0ef41Sopenharmony_ci        [
3171cb0ef41Sopenharmony_ci          'This is a problem related to network connectivity.',
3181cb0ef41Sopenharmony_ci          'In most cases you are behind a proxy or have bad network settings.',
3191cb0ef41Sopenharmony_ci          '\nIf you are behind a proxy, please make sure that the',
3201cb0ef41Sopenharmony_ci          "'proxy' config is set properly.  See: 'npm help config'",
3211cb0ef41Sopenharmony_ci        ].join('\n'),
3221cb0ef41Sopenharmony_ci      ])
3231cb0ef41Sopenharmony_ci      break
3241cb0ef41Sopenharmony_ci
3251cb0ef41Sopenharmony_ci    case 'ETARGET':
3261cb0ef41Sopenharmony_ci      short.push(['notarget', er.message])
3271cb0ef41Sopenharmony_ci      detail.push([
3281cb0ef41Sopenharmony_ci        'notarget',
3291cb0ef41Sopenharmony_ci        [
3301cb0ef41Sopenharmony_ci          'In most cases you or one of your dependencies are requesting',
3311cb0ef41Sopenharmony_ci          "a package version that doesn't exist.",
3321cb0ef41Sopenharmony_ci        ].join('\n'),
3331cb0ef41Sopenharmony_ci      ])
3341cb0ef41Sopenharmony_ci      break
3351cb0ef41Sopenharmony_ci
3361cb0ef41Sopenharmony_ci    case 'E403':
3371cb0ef41Sopenharmony_ci      short.push(['403', er.message])
3381cb0ef41Sopenharmony_ci      detail.push([
3391cb0ef41Sopenharmony_ci        '403',
3401cb0ef41Sopenharmony_ci        [
3411cb0ef41Sopenharmony_ci          'In most cases, you or one of your dependencies are requesting',
3421cb0ef41Sopenharmony_ci          'a package version that is forbidden by your security policy, or',
3431cb0ef41Sopenharmony_ci          'on a server you do not have access to.',
3441cb0ef41Sopenharmony_ci        ].join('\n'),
3451cb0ef41Sopenharmony_ci      ])
3461cb0ef41Sopenharmony_ci      break
3471cb0ef41Sopenharmony_ci
3481cb0ef41Sopenharmony_ci    case 'EBADENGINE':
3491cb0ef41Sopenharmony_ci      short.push(['engine', er.message])
3501cb0ef41Sopenharmony_ci      short.push(['engine', 'Not compatible with your version of node/npm: ' + er.pkgid])
3511cb0ef41Sopenharmony_ci      detail.push([
3521cb0ef41Sopenharmony_ci        'notsup',
3531cb0ef41Sopenharmony_ci        [
3541cb0ef41Sopenharmony_ci          'Not compatible with your version of node/npm: ' + er.pkgid,
3551cb0ef41Sopenharmony_ci          'Required: ' + JSON.stringify(er.required),
3561cb0ef41Sopenharmony_ci          'Actual:   ' +
3571cb0ef41Sopenharmony_ci            JSON.stringify({
3581cb0ef41Sopenharmony_ci              npm: npm.version,
3591cb0ef41Sopenharmony_ci              node: process.version,
3601cb0ef41Sopenharmony_ci            }),
3611cb0ef41Sopenharmony_ci        ].join('\n'),
3621cb0ef41Sopenharmony_ci      ])
3631cb0ef41Sopenharmony_ci      break
3641cb0ef41Sopenharmony_ci
3651cb0ef41Sopenharmony_ci    case 'ENOSPC':
3661cb0ef41Sopenharmony_ci      short.push(['nospc', er.message])
3671cb0ef41Sopenharmony_ci      detail.push([
3681cb0ef41Sopenharmony_ci        'nospc',
3691cb0ef41Sopenharmony_ci        [
3701cb0ef41Sopenharmony_ci          'There appears to be insufficient space on your system to finish.',
3711cb0ef41Sopenharmony_ci          'Clear up some disk space and try again.',
3721cb0ef41Sopenharmony_ci        ].join('\n'),
3731cb0ef41Sopenharmony_ci      ])
3741cb0ef41Sopenharmony_ci      break
3751cb0ef41Sopenharmony_ci
3761cb0ef41Sopenharmony_ci    case 'EROFS':
3771cb0ef41Sopenharmony_ci      short.push(['rofs', er.message])
3781cb0ef41Sopenharmony_ci      detail.push([
3791cb0ef41Sopenharmony_ci        'rofs',
3801cb0ef41Sopenharmony_ci        [
3811cb0ef41Sopenharmony_ci          'Often virtualized file systems, or other file systems',
3821cb0ef41Sopenharmony_ci          "that don't support symlinks, give this error.",
3831cb0ef41Sopenharmony_ci        ].join('\n'),
3841cb0ef41Sopenharmony_ci      ])
3851cb0ef41Sopenharmony_ci      break
3861cb0ef41Sopenharmony_ci
3871cb0ef41Sopenharmony_ci    case 'ENOENT':
3881cb0ef41Sopenharmony_ci      short.push(['enoent', er.message])
3891cb0ef41Sopenharmony_ci      detail.push([
3901cb0ef41Sopenharmony_ci        'enoent',
3911cb0ef41Sopenharmony_ci        [
3921cb0ef41Sopenharmony_ci          'This is related to npm not being able to find a file.',
3931cb0ef41Sopenharmony_ci          er.file ? "\nCheck if the file '" + er.file + "' is present." : '',
3941cb0ef41Sopenharmony_ci        ].join('\n'),
3951cb0ef41Sopenharmony_ci      ])
3961cb0ef41Sopenharmony_ci      break
3971cb0ef41Sopenharmony_ci
3981cb0ef41Sopenharmony_ci    case 'EMISSINGARG':
3991cb0ef41Sopenharmony_ci    case 'EUNKNOWNTYPE':
4001cb0ef41Sopenharmony_ci    case 'EINVALIDTYPE':
4011cb0ef41Sopenharmony_ci    case 'ETOOMANYARGS':
4021cb0ef41Sopenharmony_ci      short.push(['typeerror', er.stack])
4031cb0ef41Sopenharmony_ci      detail.push([
4041cb0ef41Sopenharmony_ci        'typeerror',
4051cb0ef41Sopenharmony_ci        [
4061cb0ef41Sopenharmony_ci          'This is an error with npm itself. Please report this error at:',
4071cb0ef41Sopenharmony_ci          '    https://github.com/npm/cli/issues',
4081cb0ef41Sopenharmony_ci        ].join('\n'),
4091cb0ef41Sopenharmony_ci      ])
4101cb0ef41Sopenharmony_ci      break
4111cb0ef41Sopenharmony_ci
4121cb0ef41Sopenharmony_ci    default:
4131cb0ef41Sopenharmony_ci      short.push(['', er.message || er])
4141cb0ef41Sopenharmony_ci      if (er.signal) {
4151cb0ef41Sopenharmony_ci        detail.push(['signal', er.signal])
4161cb0ef41Sopenharmony_ci      }
4171cb0ef41Sopenharmony_ci
4181cb0ef41Sopenharmony_ci      if (er.cmd && Array.isArray(er.args)) {
4191cb0ef41Sopenharmony_ci        detail.push(['command', ...[er.cmd, ...er.args.map(replaceInfo)]])
4201cb0ef41Sopenharmony_ci      }
4211cb0ef41Sopenharmony_ci
4221cb0ef41Sopenharmony_ci      if (er.stdout) {
4231cb0ef41Sopenharmony_ci        detail.push(['', er.stdout.trim()])
4241cb0ef41Sopenharmony_ci      }
4251cb0ef41Sopenharmony_ci
4261cb0ef41Sopenharmony_ci      if (er.stderr) {
4271cb0ef41Sopenharmony_ci        detail.push(['', er.stderr.trim()])
4281cb0ef41Sopenharmony_ci      }
4291cb0ef41Sopenharmony_ci
4301cb0ef41Sopenharmony_ci      break
4311cb0ef41Sopenharmony_ci  }
4321cb0ef41Sopenharmony_ci  return { summary: short, detail, files, json: jsonError(er, npm, { summary: short, detail }) }
4331cb0ef41Sopenharmony_ci}
4341cb0ef41Sopenharmony_ci
4351cb0ef41Sopenharmony_cimodule.exports = errorMessage
436