-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
globals: introduce prompt
on global
#38552
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -333,5 +333,6 @@ module.exports = { | |
btoa: 'readable', | ||
atob: 'readable', | ||
performance: 'readable', | ||
prompt: 'readable' | ||
}, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -294,6 +294,26 @@ added: v0.1.7 | |
|
||
The process object. See the [`process` object][] section. | ||
|
||
## `prompt([message[, defaultValue]])` | ||
<!-- YAML | ||
added: REPLACEME | ||
--> | ||
|
||
<!-- type=global --> | ||
|
||
* `message` {string} Optional, Message shown to user. Default: `'prompt'`. | ||
* `defaultValue` {string} Optional, Returned value when user inputs the | ||
empty string. | ||
* Returns: {string|null} | ||
|
||
`prompt()` the given message and waits for the user's input. | ||
If the `stdin` is not interactive, it returns `null`. | ||
If default value is not given and the user's input is empty string, it also | ||
returns `null`. | ||
If default value is given and the user's input is empty string, it returns | ||
`defaultValue`. | ||
Otherwise, it returns the user's input as `string`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should describe in here whether this method blocks the progression of the event loop or not. |
||
|
||
## `queueMicrotask(callback)` | ||
<!-- YAML | ||
added: v11.0.0 | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -48,6 +48,7 @@ const { | |||||
ObjectSetPrototypeOf, | ||||||
ReflectGet, | ||||||
ReflectSet, | ||||||
Uint8Array, | ||||||
SymbolToStringTag, | ||||||
globalThis, | ||||||
} = primordials; | ||||||
|
@@ -246,6 +247,60 @@ if (!config.noBrowserGlobals) { | |||||
return performance; | ||||||
}); | ||||||
|
||||||
defineOperation(globalThis, 'prompt', function prompt( | ||||||
message = 'prompt', | ||||||
defaultValue | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
) { | ||||||
const { validateString } = require('internal/validators'); | ||||||
validateString(message); | ||||||
if (defaultValue !== undefined) { | ||||||
validateString(defaultValue); | ||||||
} | ||||||
|
||||||
defaultValue ??= null; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
if (!process.stdin.isTTY) { | ||||||
return null; | ||||||
} | ||||||
|
||||||
process.stdout.write(message + '\r\n'); | ||||||
const res = readFromStdInSync(); | ||||||
return res || defaultValue; | ||||||
|
||||||
// Mimic implementation of `prompt` of deno | ||||||
function readFromStdInSync() { | ||||||
const fs = require('fs'); | ||||||
const LF = '\n'.charCodeAt(0); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Use primordials for consistency. |
||||||
const CR = '\r'.charCodeAt(0); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Same case as above. |
||||||
const charaBuf = new Uint8Array(1); | ||||||
const stdfd = process.platform === 'win32' ? | ||||||
process.stdin.fd : | ||||||
fs.openSync('/dev/tty', 'r'); | ||||||
const res = []; | ||||||
|
||||||
while (true) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My preference would be to implement this in terms of the functionality already available in The use of sync fs methods can also be problematic here. I'm +1 on the idea of getting this into core but I don't think the impl as it is now is the right way. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe it could go into const answer = await process.stdin.prompt('Question?\n'); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd try to implement it on the top of |
||||||
const bytesRead = fs.readSync(stdfd, charaBuf, 0, 1); | ||||||
if (bytesRead === 0) { | ||||||
break; | ||||||
} | ||||||
if (charaBuf[0] === CR) { | ||||||
const bytesRead = fs.readSync(stdfd, charaBuf, 0, 1); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This kind of implementation is going to be inherently flaky in cases in which |
||||||
if (charaBuf[0] === LF) { | ||||||
break; | ||||||
} | ||||||
res.push(CR); | ||||||
if (bytesRead === 0) { | ||||||
break; | ||||||
} | ||||||
} | ||||||
if (charaBuf[0] === LF) { | ||||||
break; | ||||||
} | ||||||
res.push(charaBuf[0]); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
} | ||||||
return new TextDecoder().decode(new Uint8Array(res)); | ||||||
} | ||||||
}); | ||||||
|
||||||
// Non-standard extensions: | ||||||
defineOperation(globalThis, 'clearImmediate', timers.clearImmediate); | ||||||
defineOperation(globalThis, 'setImmediate', timers.setImmediate); | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
sushi | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you test with non-ASCII characters please? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have tried one time, but it seems throwing confusing error. I'd try again in my next PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My guess is that is overflows the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems that implementation works in REPL well, but fails in test. My guess is that REPL
Test
Resolved, it is problem with python 2, using python 3 works fine. |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
'use strict'; | ||
|
||
const common = require('../common'); | ||
const assert = require('assert'); | ||
|
||
(async () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's no reason for this to be wrapped in an async function. |
||
const resp1 = prompt('what your favorite food?'); | ||
assert.strictEqual(resp1, 'sushi'); | ||
|
||
const resp2 = prompt('what is the default value?', 'DEFAULT'); | ||
assert.strictEqual(resp2, 'DEFAULT'); | ||
})().then(common.mustCall(() => {})); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
sushi | ||
what your favorite food? | ||
what is the default value? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.