1// This is separate to indicate that it should contain code we expect to work in 2// all versions of node >= 6. This is a best effort to catch syntax errors to 3// give users a good error message if they are using a node version that doesn't 4// allow syntax we are using such as private properties, etc. This file is 5// linted with ecmaVersion=6 so we don't use invalid syntax, which is set in the 6// .eslintrc.local.json file 7 8const { engines: { node: engines }, version } = require('../../package.json') 9const npm = `v${version}` 10 11module.exports = (process, getCli) => { 12 const node = process.version 13 14 /* eslint-disable-next-line max-len */ 15 const unsupportedMessage = `npm ${npm} does not support Node.js ${node}. This version of npm supports the following node versions: \`${engines}\`. You can find the latest version at https://nodejs.org/.` 16 17 /* eslint-disable-next-line max-len */ 18 const brokenMessage = `ERROR: npm ${npm} is known not to run on Node.js ${node}. This version of npm supports the following node versions: \`${engines}\`. You can find the latest version at https://nodejs.org/.` 19 20 // coverage ignored because this is only hit in very unsupported node versions 21 // and it's a best effort attempt to show something nice in those cases 22 /* istanbul ignore next */ 23 const syntaxErrorHandler = (err) => { 24 if (err instanceof SyntaxError) { 25 // eslint-disable-next-line no-console 26 console.error(`${brokenMessage}\n\nERROR:`) 27 // eslint-disable-next-line no-console 28 console.error(err) 29 return process.exit(1) 30 } 31 throw err 32 } 33 34 process.on('uncaughtException', syntaxErrorHandler) 35 process.on('unhandledRejection', syntaxErrorHandler) 36 37 // require this only after setting up the error handlers 38 const cli = getCli() 39 return cli(process, { 40 node, 41 npm, 42 engines, 43 unsupportedMessage, 44 off: () => { 45 process.off('uncaughtException', syntaxErrorHandler) 46 process.off('unhandledRejection', syntaxErrorHandler) 47 }, 48 }) 49} 50