| #!/usr/bin/env node | 
|   | 
| // @ts-ignore | 
| process.exitCode = 0; | 
|   | 
| /** | 
|  * @param {string} command process to run | 
|  * @param {string[]} args commandline arguments | 
|  * @returns {Promise<void>} promise | 
|  */ | 
| const runCommand = (command, args) => { | 
|     const cp = require("child_process"); | 
|     return new Promise((resolve, reject) => { | 
|         const executedCommand = cp.spawn(command, args, { | 
|             stdio: "inherit", | 
|             shell: true | 
|         }); | 
|   | 
|         executedCommand.on("error", error => { | 
|             reject(error); | 
|         }); | 
|   | 
|         executedCommand.on("exit", code => { | 
|             if (code === 0) { | 
|                 resolve(); | 
|             } else { | 
|                 reject(); | 
|             } | 
|         }); | 
|     }); | 
| }; | 
|   | 
| /** | 
|  * @param {string} packageName name of the package | 
|  * @returns {boolean} is the package installed? | 
|  */ | 
| const isInstalled = packageName => { | 
|     try { | 
|         require.resolve(packageName); | 
|   | 
|         return true; | 
|     } catch (err) { | 
|         return false; | 
|     } | 
| }; | 
|   | 
| /** | 
|  * @typedef {Object} CliOption | 
|  * @property {string} name display name | 
|  * @property {string} package npm package name | 
|  * @property {string} binName name of the executable file | 
|  * @property {string} alias shortcut for choice | 
|  * @property {boolean} installed currently installed? | 
|  * @property {boolean} recommended is recommended | 
|  * @property {string} url homepage | 
|  * @property {string} description description | 
|  */ | 
|   | 
| /** @type {CliOption[]} */ | 
| const CLIs = [ | 
|     { | 
|         name: "webpack-cli", | 
|         package: "webpack-cli", | 
|         binName: "webpack-cli", | 
|         alias: "cli", | 
|         installed: isInstalled("webpack-cli"), | 
|         recommended: true, | 
|         url: "https://github.com/webpack/webpack-cli", | 
|         description: "The original webpack full-featured CLI." | 
|     }, | 
|     { | 
|         name: "webpack-command", | 
|         package: "webpack-command", | 
|         binName: "webpack-command", | 
|         alias: "command", | 
|         installed: isInstalled("webpack-command"), | 
|         recommended: false, | 
|         url: "https://github.com/webpack-contrib/webpack-command", | 
|         description: "A lightweight, opinionated webpack CLI." | 
|     } | 
| ]; | 
|   | 
| const installedClis = CLIs.filter(cli => cli.installed); | 
|   | 
| if (installedClis.length === 0) { | 
|     const path = require("path"); | 
|     const fs = require("fs"); | 
|     const readLine = require("readline"); | 
|   | 
|     let notify = | 
|         "One CLI for webpack must be installed. These are recommended choices, delivered as separate packages:"; | 
|   | 
|     for (const item of CLIs) { | 
|         if (item.recommended) { | 
|             notify += `\n - ${item.name} (${item.url})\n   ${item.description}`; | 
|         } | 
|     } | 
|   | 
|     console.error(notify); | 
|   | 
|     const isYarn = fs.existsSync(path.resolve(process.cwd(), "yarn.lock")); | 
|   | 
|     const packageManager = isYarn ? "yarn" : "npm"; | 
|     const installOptions = [isYarn ? "add" : "install", "-D"]; | 
|   | 
|     console.error( | 
|         `We will use "${packageManager}" to install the CLI via "${packageManager} ${installOptions.join( | 
|             " " | 
|         )}".` | 
|     ); | 
|   | 
|     const question = `Do you want to install 'webpack-cli' (yes/no): `; | 
|   | 
|     const questionInterface = readLine.createInterface({ | 
|         input: process.stdin, | 
|         output: process.stderr | 
|     }); | 
|     questionInterface.question(question, answer => { | 
|         questionInterface.close(); | 
|   | 
|         const normalizedAnswer = answer.toLowerCase().startsWith("y"); | 
|   | 
|         if (!normalizedAnswer) { | 
|             console.error( | 
|                 "You need to install 'webpack-cli' to use webpack via CLI.\n" + | 
|                     "You can also install the CLI manually." | 
|             ); | 
|             process.exitCode = 1; | 
|   | 
|             return; | 
|         } | 
|   | 
|         const packageName = "webpack-cli"; | 
|   | 
|         console.log( | 
|             `Installing '${packageName}' (running '${packageManager} ${installOptions.join( | 
|                 " " | 
|             )} ${packageName}')...` | 
|         ); | 
|   | 
|         runCommand(packageManager, installOptions.concat(packageName)) | 
|             .then(() => { | 
|                 require(packageName); //eslint-disable-line | 
|             }) | 
|             .catch(error => { | 
|                 console.error(error); | 
|                 process.exitCode = 1; | 
|             }); | 
|     }); | 
| } else if (installedClis.length === 1) { | 
|     const path = require("path"); | 
|     const pkgPath = require.resolve(`${installedClis[0].package}/package.json`); | 
|     // eslint-disable-next-line node/no-missing-require | 
|     const pkg = require(pkgPath); | 
|     // eslint-disable-next-line node/no-missing-require | 
|     require(path.resolve( | 
|         path.dirname(pkgPath), | 
|         pkg.bin[installedClis[0].binName] | 
|     )); | 
| } else { | 
|     console.warn( | 
|         `You have installed ${installedClis | 
|             .map(item => item.name) | 
|             .join( | 
|                 " and " | 
|             )} together. To work with the "webpack" command you need only one CLI package, please remove one of them or use them directly via their binary.` | 
|     ); | 
|   | 
|     // @ts-ignore | 
|     process.exitCode = 1; | 
| } |