11

I have an npm script, which is run like that:

npm run start:local -- -target.location https://192.1.1.1:8052/

The URL param is the local IP of a user.

What I would love to have is to ask users to input this value, because it's different for everybody.

Is it possible? Would be great to do it with vanila npm scripts.

Mark Dolbyrev
  • 1,887
  • 1
  • 17
  • 24
  • Does this answer your question? [Sending command line arguments to npm script](https://stackoverflow.com/questions/11580961/sending-command-line-arguments-to-npm-script) – SNikhill Apr 18 '21 at 16:34
  • Nope, it does not (or at least I can't find how it suggests to ask users for inputting params). – Mark Dolbyrev Apr 22 '21 at 07:13
  • Your can call a bash script from your npm script that reads in a parameter from the user. There's lots of examples of interactive bash scripts out there. – windowsill Apr 22 '21 at 07:41
  • However in node land I'd expect to have to run this as URL=localhost npm run start – windowsill Apr 22 '21 at 07:42
  • 2
    What is the contents of the "scripts" property of your `package.json` file? – Trott Apr 22 '21 at 19:17
  • @MarkDolbyrev - What is the intended UX for your requirement? Are the steps as follows (or something else)? **1)** User runs `npm run start:local` via CLI **2)** User is asked to enter local IP address and port number via CLI. **3)** User types/enters e.g. `192.1.1.1:8052` via CLI **4)** An argument/parameter is formed to produce e.g. `-target.location https://192.1.1.1:8052/` _(based on user input from step 3)_ **5)** The resultant argument is then appended to a command which is then invoked..... Please clarify, and also provide details about the command(s) that should be invoked . – RobC Apr 24 '21 at 10:55
  • @RobC, your steps describe exactly what I need. – Mark Dolbyrev Apr 26 '21 at 11:39
  • The whole approach is rather questionable, when the user has to lookup the IP. Besides the local loopback interface `127.0.0.1` suffices for a local install to test with (more complexity than required). Selecting one from available interfaces would rather be good UX, which properly supports laziness. – Martin Zeitler Apr 29 '21 at 04:17

4 Answers4

9

Simply speaking, an npm script will run the desired command in your shell environment.

In a shell script, the arguments passed can be accessed using $N where N = Position of the argument.

Talking about your case, the command you want to run is npm run start:local -- -target.location USER_INPUT USER_INPUT needs to replaced with the argument that the user has passed. Assuming that the user will pass location as the first argument to the script, it can be accessed using $1.

I have created this gist to demonstrate the same.

enter image description here

As you can clearly see, I have defined start:local to access the first argument and then, pass it to the start script which then echoes out the passed in argument.

enter image description here

UPDATE: Here is the script for ASKING a value from a user in a prompt format. enter image description here

Basically, first I am asking for user input then, storing the same in a variable and passing the variable as an argument to npm start

enter image description here

References

SNikhill
  • 446
  • 2
  • 8
  • As far as I understand the code doesn't ASK users to input some values. Am I missing smth? – Mark Dolbyrev Apr 23 '21 at 08:32
  • I see. So, you want a prompt rather than passing the location as an argument, right? – SNikhill Apr 23 '21 at 08:51
  • The answer has been updated to include the "ASK" functionality. – SNikhill Apr 23 '21 at 09:03
  • It looks like your solution requires some bash scripts (does the "read location" command runs some sort of a bash script?). I would love to avoid it and use vanila npm (if possible). – Mark Dolbyrev Apr 26 '21 at 11:41
  • Nope, it is not a bash script. It is a bash syntax to accept the input from the `stdin`. But, I believe your question was regarding the concern with windows user. In that case, I recommend running all the `npm scripts` in [a bash environment accessible using `git-bash`](https://stackoverflow.com/questions/23243353/how-to-set-shell-for-npm-run-scripts-in-windows). – SNikhill Apr 27 '21 at 09:21
8

Use readline to get the ip value then use exec to spawn this process. This is a pure JS solution, and OS agnostic.

Example:

package.json
"scripts": {
    "start": "npm run start:local -- -target.location",
    "prompt": "node prompt.js"
},
prompt.js
const { spawn, execSync } = require('child_process');
const exec = commands => {
  execSync(commands, { stdio: 'inherit', shell: true });
};
const spawnProcess = commands => {
  spawn(commands, { stdio: 'inherit', shell: true });
};
   const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.question('What is your current ip? example: https://192.168.1.10:9009 ', (ip) => {
  console.log(`Starting server on: ${ip}`);
  exec(`npm run start -- ${ip}`);
  rl.close();
});
ProllyGeek
  • 15,517
  • 9
  • 53
  • 72
3

Example: If we want to run below three commands in sequence with userinput

git add .
git commit -m "With git commit message at run time"
git push

Add below command in your package.json file under the scripts

"gitPush": "git add . && echo 'Enter Commit Message' && read message && git commit -m \"$message\" && git push"

enter image description here

And run commands via npm run gitPush

enter image description here

References: ask-users-to-input-value-for-npm-script

Hardik Desai
  • 1,089
  • 12
  • 20
0

If you're trying to ask for users to input ther response you could do something like this.

const readline = require("readline");

const reader = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
    error: process.stderr
});

const ask = (message, default_value = null) => new Promise(resolve => {
    reader.question(message, (response)=>{
        return resolve(response.length >= 1 ? response : default_value);
    });
});

(()=>{
    let ip = await ask(`Please enter your public ip: `);
})();
Eduardo Jiménez
  • 351
  • 3
  • 13