diff options
author | Julian Møller Ellehauge <jumoel@github.com> | 2022-06-22 23:58:41 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-22 23:58:41 +0300 |
commit | 06fd788f79e16da04d6e96aa56416cd2698f057a (patch) | |
tree | 7ca9e6a884b2b64cb65ac791fda52b8d2b963ea6 /lib/utils | |
parent | aab4079e810c06ff5fa847cbd53b5d7bab3dd24f (diff) |
feat: prompt before opening web-login URL when performing `login`/`adduser` (#4960)
Prompt before opening web-login URL when performing login/adduser
Diffstat (limited to 'lib/utils')
-rw-r--r-- | lib/utils/open-url-prompt.js | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/lib/utils/open-url-prompt.js b/lib/utils/open-url-prompt.js new file mode 100644 index 000000000..3eb3ac288 --- /dev/null +++ b/lib/utils/open-url-prompt.js @@ -0,0 +1,69 @@ +const readline = require('readline') +const opener = require('opener') + +function print (npm, title, url) { + const json = npm.config.get('json') + + const message = json ? JSON.stringify({ title, url }) : `${title}:\n${url}` + + npm.output(message) +} + +// Prompt to open URL in browser if possible +const promptOpen = async (npm, url, title, prompt, emitter) => { + const browser = npm.config.get('browser') + const isInteractive = process.stdin.isTTY === true && process.stdout.isTTY === true + + try { + if (!/^https?:$/.test(new URL(url).protocol)) { + throw new Error() + } + } catch (_) { + throw new Error('Invalid URL: ' + url) + } + + print(npm, title, url) + + if (browser === false || !isInteractive) { + return + } + + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }) + + const tryOpen = await new Promise(resolve => { + rl.question(prompt, () => { + resolve(true) + }) + + if (emitter && emitter.addListener) { + emitter.addListener('abort', () => { + rl.close() + + // clear the prompt line + npm.output('') + + resolve(false) + }) + } + }) + + if (!tryOpen) { + return + } + + const command = browser === true ? null : browser + await new Promise((resolve, reject) => { + opener(url, { command }, err => { + if (err) { + return reject(err) + } + + return resolve() + }) + }) +} + +module.exports = promptOpen |