@reliverse/relinka 1.1.5 → 1.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-npm/components/anykey/index.js +77 -57
- package/dist-npm/components/block/block.js +61 -48
- package/dist-npm/components/checkbox/index.js +211 -178
- package/dist-npm/components/confirm/confirm-main.js +122 -85
- package/dist-npm/components/confirm/confirm-three.js +27 -24
- package/dist-npm/components/confirm/index.js +45 -36
- package/dist-npm/components/core/Separator.js +17 -15
- package/dist-npm/components/core/create-prompt.js +124 -101
- package/dist-npm/components/core/errors.js +15 -19
- package/dist-npm/components/core/hook-engine.js +120 -91
- package/dist-npm/components/core/index.js +12 -12
- package/dist-npm/components/core/key.js +6 -16
- package/dist-npm/components/core/lines.js +54 -45
- package/dist-npm/components/core/make-theme.js +30 -21
- package/dist-npm/components/core/position.js +23 -27
- package/dist-npm/components/core/promise-polyfill.js +14 -11
- package/dist-npm/components/core/screen-manager.js +74 -59
- package/dist-npm/components/core/theme.js +32 -22
- package/dist-npm/components/core/use-effect.js +15 -9
- package/dist-npm/components/core/use-keypress.js +23 -19
- package/dist-npm/components/core/use-memo.js +16 -10
- package/dist-npm/components/core/use-pagination.js +32 -33
- package/dist-npm/components/core/use-prefix.js +38 -40
- package/dist-npm/components/core/use-ref.js +5 -2
- package/dist-npm/components/core/use-state.js +23 -15
- package/dist-npm/components/core/useKeyPress.js +17 -14
- package/dist-npm/components/core/usePromptState.js +14 -8
- package/dist-npm/components/core/utils.js +16 -7
- package/dist-npm/components/date/date.js +204 -167
- package/dist-npm/components/editor/index.js +92 -71
- package/dist-npm/components/expand/index.js +124 -96
- package/dist-npm/components/figures/index.js +294 -283
- package/dist-npm/components/input/index.js +87 -61
- package/dist-npm/components/input/text-main.js +124 -97
- package/dist-npm/components/input/text.js +28 -24
- package/dist-npm/components/instance/basic.js +25 -17
- package/dist-npm/components/instance/browser.js +18 -14
- package/dist-npm/components/instance/reporter/basic.js +65 -46
- package/dist-npm/components/instance/reporter/browser.js +47 -44
- package/dist-npm/components/instance/reporter/fancy.js +96 -83
- package/dist-npm/components/instance/shared.js +2 -2
- package/dist-npm/components/mono/mono.js +62 -52
- package/dist-npm/components/mono/monoTwo.js +49 -35
- package/dist-npm/components/multiselect/group-multiselect.js +71 -55
- package/dist-npm/components/multiselect/multi-select-two.js +130 -97
- package/dist-npm/components/multiselect/multi-select.js +49 -43
- package/dist-npm/components/multiselect/multiselect-main.js +146 -120
- package/dist-npm/components/multiselect/num-multi-select.js +130 -97
- package/dist-npm/components/multiselect/num-multiselect-main.js +35 -24
- package/dist-npm/components/next-steps/next-steps.js +25 -23
- package/dist-npm/components/number/index.js +112 -78
- package/dist-npm/components/number/number-main.js +2 -95
- package/dist-npm/components/password/index.js +73 -54
- package/dist-npm/components/password/password-main.js +2 -119
- package/dist-npm/components/password/password-three.js +30 -26
- package/dist-npm/components/progressbar/ProgressBar.js +64 -45
- package/dist-npm/components/progressbar/helper.js +40 -33
- package/dist-npm/components/progressbar/index.js +1 -1
- package/dist-npm/components/prompts/create.js +44 -29
- package/dist-npm/components/prompts/index.js +45 -45
- package/dist-npm/components/prompts/prompt.js +260 -211
- package/dist-npm/components/prompts/promptTwo.js +605 -561
- package/dist-npm/components/prompts/relinka.js +295 -237
- package/dist-npm/components/range/range.js +294 -247
- package/dist-npm/components/rawlist/index.js +107 -87
- package/dist-npm/components/results/results.js +37 -31
- package/dist-npm/components/search/index.js +193 -148
- package/dist-npm/components/select/index.js +186 -148
- package/dist-npm/components/select/num-select-main.js +27 -27
- package/dist-npm/components/select/num-select.js +5 -124
- package/dist-npm/components/select/select-key.js +25 -24
- package/dist-npm/components/select/select-main.js +133 -109
- package/dist-npm/components/select/select-three.js +36 -32
- package/dist-npm/components/select/select-two.js +87 -94
- package/dist-npm/components/spinner/index.js +136 -107
- package/dist-npm/components/st-end/end.js +26 -34
- package/dist-npm/components/st-end/start.js +15 -29
- package/dist-npm/components/toggle/index.js +137 -113
- package/dist-npm/components/visual/animate/animate.js +10 -53
- package/dist-npm/components/visual/ascii-art/ascii-art.js +1 -12
- package/dist-npm/mod.js +2 -1
- package/dist-npm/testing/index.js +83 -58
- package/dist-npm/types/general.js +1 -0
- package/dist-npm/types/index.js +3 -2
- package/dist-npm/types/keypress.js +36 -35
- package/dist-npm/types/readline.js +1 -0
- package/dist-npm/types/relinka.js +1 -0
- package/dist-npm/types/utils.js +1 -0
- package/dist-npm/utils/box.js +137 -135
- package/dist-npm/utils/color.js +74 -65
- package/dist-npm/utils/colorize.js +156 -124
- package/dist-npm/utils/component.js +657 -532
- package/dist-npm/utils/constants.js +63 -64
- package/dist-npm/utils/core.js +3 -2
- package/dist-npm/utils/decoder.js +223 -244
- package/dist-npm/utils/error.js +9 -4
- package/dist-npm/utils/errors.js +4 -14
- package/dist-npm/utils/format.js +24 -19
- package/dist-npm/utils/keypress.js +414 -316
- package/dist-npm/utils/log.js +15 -11
- package/dist-npm/utils/mapping.js +52 -45
- package/dist-npm/utils/messages.js +183 -183
- package/dist-npm/utils/platforms.js +20 -16
- package/dist-npm/utils/prompt-tmp.js +286 -235
- package/dist-npm/utils/prompt-two.js +286 -235
- package/dist-npm/utils/readline.js +7 -5
- package/dist-npm/utils/skeleton.js +170 -130
- package/dist-npm/utils/stream.js +2 -2
- package/dist-npm/utils/string.js +58 -44
- package/dist-npm/utils/terminal.js +34 -23
- package/dist-npm/utils/tree.js +41 -30
- package/dist-npm/utils/types.js +1 -0
- package/dist-npm/utils/utils.js +8 -8
- package/dist-npm/utils/variants.js +44 -36
- package/package.json +20 -28
|
@@ -1,26 +1,29 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import Prompt from
|
|
1
|
+
import {cursor} from 'sisteransi';
|
|
2
|
+
import Prompt from '../prompts/prompt.js';
|
|
3
|
+
|
|
3
4
|
export default class ConfirmPrompt extends Prompt {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
5
|
+
get cursor() {
|
|
6
|
+
return this.value ? 0 : 1;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
get _value() {
|
|
10
|
+
return !this.cursor;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
constructor(opts) {
|
|
14
|
+
super(opts, false);
|
|
15
|
+
this.value = !!opts.initialValue;
|
|
16
|
+
this.on('value', () => {
|
|
17
|
+
this.value = this._value;
|
|
18
|
+
});
|
|
19
|
+
this.on('confirm', (confirm) => {
|
|
20
|
+
this.output.write(cursor.move(0, -1));
|
|
21
|
+
this.value = confirm;
|
|
22
|
+
this.state = 'submit';
|
|
23
|
+
this.close();
|
|
24
|
+
});
|
|
25
|
+
this.on('cursor', () => {
|
|
26
|
+
this.value = !this.value;
|
|
27
|
+
});
|
|
28
|
+
}
|
|
26
29
|
}
|
|
@@ -1,41 +1,50 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from
|
|
2
|
+
createPrompt,
|
|
3
|
+
useState,
|
|
4
|
+
useKeypress,
|
|
5
|
+
isEnterKey,
|
|
6
|
+
usePrefix,
|
|
7
|
+
makeTheme,
|
|
8
|
+
} from '../../components/core/index.js';
|
|
9
|
+
|
|
9
10
|
export default createPrompt((config, done) => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
11
|
+
const {transformer = (answer) => answer ? 'yes' : 'no'} = config;
|
|
12
|
+
const [status, setStatus] = useState('idle');
|
|
13
|
+
const [value, setValue] = useState('');
|
|
14
|
+
const theme = makeTheme(config.theme);
|
|
15
|
+
const prefix = usePrefix({
|
|
16
|
+
status,
|
|
17
|
+
theme,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
useKeypress((key, rl) => {
|
|
21
|
+
if (isEnterKey(key)) {
|
|
22
|
+
let answer = config.default;
|
|
23
|
+
|
|
24
|
+
if (/^(y|yes)/i.test(value)) {
|
|
25
|
+
answer = true;
|
|
26
|
+
} else if (/^(n|no)/i.test(value)) {
|
|
27
|
+
answer = false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
setValue(transformer(answer));
|
|
32
|
+
setStatus('done');
|
|
33
|
+
done(answer);
|
|
34
|
+
} else {
|
|
35
|
+
setValue(rl.line);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
let formattedValue = value;
|
|
39
|
+
let defaultValue = '';
|
|
40
|
+
|
|
41
|
+
if (status === 'done') {
|
|
42
|
+
formattedValue = theme.style.answer(value);
|
|
26
43
|
} else {
|
|
27
|
-
|
|
44
|
+
defaultValue = ` ${theme.style.defaultAnswer(!config.default ? 'y/N' : 'Y/n')}`;
|
|
28
45
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
formattedValue = theme.style.answer(value);
|
|
34
|
-
} else {
|
|
35
|
-
defaultValue = ` ${theme.style.defaultAnswer(
|
|
36
|
-
!config.default ? "y/N" : "Y/n"
|
|
37
|
-
)}`;
|
|
38
|
-
}
|
|
39
|
-
const message = theme.style.message(config.message, status);
|
|
40
|
-
return `${prefix} ${message}${defaultValue} ${formattedValue}`;
|
|
46
|
+
|
|
47
|
+
const message = theme.style.message(config.message, status);
|
|
48
|
+
|
|
49
|
+
return `${prefix} ${message}${defaultValue} ${formattedValue}`;
|
|
41
50
|
});
|
|
@@ -1,18 +1,20 @@
|
|
|
1
|
-
import colors from
|
|
2
|
-
import figures from
|
|
1
|
+
import colors from 'picocolors';
|
|
2
|
+
import figures from '../../components/figures/index.js';
|
|
3
|
+
|
|
3
4
|
export class Separator {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
separator = colors.dim(Array
|
|
6
|
+
.from({
|
|
7
|
+
length: 15,
|
|
8
|
+
})
|
|
9
|
+
.join(figures.line));
|
|
10
|
+
type = 'separator';
|
|
11
|
+
constructor(separator) {
|
|
12
|
+
if (separator) {
|
|
13
|
+
this.separator = separator;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static isSeparator(choice) {
|
|
18
|
+
return Boolean(choice && typeof choice === 'object' && 'type' in choice && choice.type === 'separator');
|
|
11
19
|
}
|
|
12
|
-
}
|
|
13
|
-
static isSeparator(choice) {
|
|
14
|
-
return Boolean(
|
|
15
|
-
choice && typeof choice === "object" && "type" in choice && choice.type === "separator"
|
|
16
|
-
);
|
|
17
|
-
}
|
|
18
20
|
}
|
|
@@ -1,107 +1,130 @@
|
|
|
1
|
-
import MuteStream from
|
|
2
|
-
import {
|
|
3
|
-
import * as readline from
|
|
4
|
-
import {
|
|
1
|
+
import MuteStream from 'mute-stream';
|
|
2
|
+
import {AsyncResource} from 'node:async_hooks';
|
|
3
|
+
import * as readline from 'node:readline';
|
|
4
|
+
import {onExit as onSignalExit} from 'signal-exit';
|
|
5
|
+
import process from 'node:process';
|
|
5
6
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
} from
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
AbortPromptError,
|
|
8
|
+
CancelPromptError,
|
|
9
|
+
ExitPromptError,
|
|
10
|
+
} from './errors.js';
|
|
11
|
+
import {
|
|
12
|
+
withHooks,
|
|
13
|
+
effectScheduler,
|
|
14
|
+
} from './hook-engine.js';
|
|
15
|
+
import {PromisePolyfill} from './promise-polyfill.js';
|
|
16
|
+
import ScreenManager from './screen-manager.js';
|
|
17
|
+
|
|
18
|
+
const isString = (a) => typeof a === 'string';
|
|
19
|
+
|
|
13
20
|
function getCallSites() {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
const _prepareStackTrace = Error.prepareStackTrace;
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
let result = [];
|
|
25
|
+
|
|
26
|
+
Error.prepareStackTrace = (_, callSites) => {
|
|
27
|
+
const callSitesWithoutCurrent = callSites.slice(1);
|
|
28
|
+
|
|
29
|
+
result = callSitesWithoutCurrent;
|
|
30
|
+
return callSitesWithoutCurrent;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
return result;
|
|
34
|
+
} finally {
|
|
35
|
+
Error.prepareStackTrace = _prepareStackTrace;
|
|
36
|
+
}
|
|
27
37
|
}
|
|
38
|
+
|
|
28
39
|
export function createPrompt(view) {
|
|
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
|
-
return withHooks(rl, (cycle) => {
|
|
66
|
-
const hooksCleanup = AsyncResource.bind(() => effectScheduler.clearAll());
|
|
67
|
-
rl.on("close", hooksCleanup);
|
|
68
|
-
cleanups.add(() => rl.removeListener("close", hooksCleanup));
|
|
69
|
-
cycle(() => {
|
|
70
|
-
try {
|
|
71
|
-
const nextView = view(config, (value) => {
|
|
72
|
-
setImmediate(() => resolve(value));
|
|
73
|
-
});
|
|
74
|
-
if (nextView === void 0) {
|
|
75
|
-
throw new Error(
|
|
76
|
-
`Prompt functions must return a string.
|
|
77
|
-
at ${callerFilename}`
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
const [content, bottomContent] = typeof nextView === "string" ? [nextView] : nextView;
|
|
81
|
-
screen.render(content, bottomContent);
|
|
82
|
-
effectScheduler.run();
|
|
83
|
-
} catch (error) {
|
|
84
|
-
reject(error);
|
|
40
|
+
const callSites = getCallSites();
|
|
41
|
+
const callerFilename = callSites[1]?.getFileName?.();
|
|
42
|
+
const prompt = (config, context = {}) => {
|
|
43
|
+
const {input = process.stdin, signal} = context;
|
|
44
|
+
const cleanups = new Set();
|
|
45
|
+
const output = new MuteStream();
|
|
46
|
+
|
|
47
|
+
output.pipe(context.output ?? process.stdout);
|
|
48
|
+
const rl = readline.createInterface({
|
|
49
|
+
terminal: true,
|
|
50
|
+
input,
|
|
51
|
+
output,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const screen = new ScreenManager(rl);
|
|
55
|
+
const {
|
|
56
|
+
promise,
|
|
57
|
+
resolve,
|
|
58
|
+
reject,
|
|
59
|
+
} = PromisePolyfill.withResolver();
|
|
60
|
+
const cancel = () => reject(new CancelPromptError());
|
|
61
|
+
|
|
62
|
+
if (signal) {
|
|
63
|
+
const abort = () => reject(new AbortPromptError({
|
|
64
|
+
cause: signal.reason,
|
|
65
|
+
}));
|
|
66
|
+
|
|
67
|
+
if (signal.aborted) {
|
|
68
|
+
abort();
|
|
69
|
+
return Object.assign(promise, {
|
|
70
|
+
cancel,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
signal.addEventListener('abort', abort);
|
|
75
|
+
cleanups.add(() => signal.removeEventListener('abort', abort));
|
|
85
76
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
effectScheduler.clearAll();
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
77
|
+
|
|
78
|
+
cleanups.add(onSignalExit((code, signal2) => {
|
|
79
|
+
reject(new ExitPromptError(`User force closed the prompt with ${code} ${signal2}`));
|
|
80
|
+
}));
|
|
81
|
+
const checkCursorPos = () => screen.checkCursorPos();
|
|
82
|
+
rl.input.on('keypress', checkCursorPos);
|
|
83
|
+
cleanups.add(() => rl.input.removeListener('keypress', checkCursorPos));
|
|
84
|
+
return withHooks(rl, (cycle) => {
|
|
85
|
+
const hooksCleanup = AsyncResource.bind(() => effectScheduler.clearAll());
|
|
86
|
+
rl.on('close', hooksCleanup);
|
|
87
|
+
cleanups.add(() => rl.removeListener('close', hooksCleanup));
|
|
88
|
+
cycle(() => {
|
|
89
|
+
try {
|
|
90
|
+
const nextView = view(config, (value) => {
|
|
91
|
+
setImmediate(() => resolve(value));
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
if (nextView === void 0) {
|
|
95
|
+
throw Error(`Prompt functions must return a string.
|
|
96
|
+
at ${callerFilename}`);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const [content, bottomContent] = isString(nextView) ? [nextView] : nextView;
|
|
100
|
+
screen.render(content, bottomContent);
|
|
101
|
+
effectScheduler.run();
|
|
102
|
+
} catch(error) {
|
|
103
|
+
reject(error);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
return Object.assign(promise
|
|
107
|
+
.then((answer) => {
|
|
108
|
+
effectScheduler.clearAll();
|
|
109
|
+
return answer;
|
|
110
|
+
}, (error) => {
|
|
111
|
+
effectScheduler.clearAll();
|
|
112
|
+
throw error;
|
|
113
|
+
})
|
|
114
|
+
.finally(() => {
|
|
115
|
+
for (const cleanup of cleanups)
|
|
116
|
+
cleanup();
|
|
117
|
+
|
|
118
|
+
screen.done({
|
|
119
|
+
clearContent: Boolean(context.clearPromptOnDone),
|
|
120
|
+
});
|
|
121
|
+
output.end();
|
|
122
|
+
})
|
|
123
|
+
.then(() => promise), {
|
|
124
|
+
cancel,
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
return prompt;
|
|
107
130
|
}
|
|
@@ -1,21 +1,17 @@
|
|
|
1
1
|
export class AbortPromptError extends Error {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export class
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
name = "HookError";
|
|
18
|
-
}
|
|
19
|
-
export class ValidationError extends Error {
|
|
20
|
-
name = "ValidationError";
|
|
2
|
+
name = 'AbortPromptError';
|
|
3
|
+
message = 'Prompt was aborted';
|
|
4
|
+
constructor(options) {
|
|
5
|
+
super();
|
|
6
|
+
this.cause = options?.cause;
|
|
7
|
+
}
|
|
8
|
+
}export class CancelPromptError extends Error {
|
|
9
|
+
name = 'CancelPromptError';
|
|
10
|
+
message = 'Prompt was canceled';
|
|
11
|
+
}export class ExitPromptError extends Error {
|
|
12
|
+
name = 'ExitPromptError';
|
|
13
|
+
}export class HookError extends Error {
|
|
14
|
+
name = 'HookError';
|
|
15
|
+
}export class ValidationError extends Error {
|
|
16
|
+
name = 'ValidationError';
|
|
21
17
|
}
|