-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
index.ts
75 lines (66 loc) · 2.12 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import {
createPrompt,
useState,
useKeypress,
usePrefix,
isEnterKey,
isBackspaceKey,
AsyncPromptConfig,
} from '@inquirer/core';
import chalk from 'chalk';
type InputConfig = AsyncPromptConfig & {
default?: string;
transformer?: (value: string, { isFinal }: { isFinal: boolean }) => string;
};
export default createPrompt<string, InputConfig>((config, done) => {
const [status, setStatus] = useState<string>('pending');
const [defaultValue, setDefaultValue] = useState<string | undefined>(config.default);
const [errorMsg, setError] = useState<string | undefined>(undefined);
const [value, setValue] = useState<string>('');
const isLoading = status === 'loading';
const prefix = usePrefix(isLoading);
useKeypress(async (key, rl) => {
// Ignore keypress while our prompt is doing other processing.
if (status !== 'pending') {
return;
}
if (isEnterKey(key)) {
const answer = value || defaultValue || '';
setStatus('loading');
const isValid = await config.validate(answer);
if (isValid === true) {
setValue(answer);
setStatus('done');
done(answer);
} else {
// TODO: Can we keep the value after validation failure?
// `rl.line = value` works but it looses the cursor position.
setValue('');
setError(isValid || 'You must provide a valid value');
setStatus('pending');
}
} else if (isBackspaceKey(key) && !value) {
setDefaultValue(undefined);
} else {
setValue(rl.line);
setError(undefined);
}
});
const message = chalk.bold(config.message);
let formattedValue = value;
if (typeof config.transformer === 'function') {
formattedValue = config.transformer(value, { isFinal: status === 'done' });
}
if (status === 'done') {
formattedValue = chalk.cyan(formattedValue);
}
let defaultStr = '';
if (defaultValue && status !== 'done' && !value) {
defaultStr = chalk.dim(` (${defaultValue})`);
}
let error = '';
if (errorMsg) {
error = chalk.red(`> ${errorMsg}`);
}
return [`${prefix} ${message}${defaultStr} ${formattedValue}`, error];
});