@reliverse/relinka 1.0.0
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/LICENSE.md +21 -0
- package/README.md +141 -0
- package/output/components/animate.d.ts +13 -0
- package/output/components/animate.js +55 -0
- package/output/components/any-key.d.ts +7 -0
- package/output/components/any-key.js +56 -0
- package/output/components/ascii-art.d.ts +6 -0
- package/output/components/ascii-art.js +12 -0
- package/output/components/confirm.d.ts +3 -0
- package/output/components/confirm.js +99 -0
- package/output/components/date.d.ts +6 -0
- package/output/components/date.js +125 -0
- package/output/components/end.d.ts +2 -0
- package/output/components/end.js +36 -0
- package/output/components/mono.d.ts +5 -0
- package/output/components/mono.js +64 -0
- package/output/components/next-steps.d.ts +2 -0
- package/output/components/next-steps.js +25 -0
- package/output/components/num-multi-select.d.ts +3 -0
- package/output/components/num-multi-select.js +108 -0
- package/output/components/num-select.d.ts +5 -0
- package/output/components/num-select.js +122 -0
- package/output/components/number.d.ts +3 -0
- package/output/components/number.js +92 -0
- package/output/components/password.d.ts +3 -0
- package/output/components/password.js +117 -0
- package/output/components/results.d.ts +10 -0
- package/output/components/results.js +34 -0
- package/output/components/select.d.ts +2 -0
- package/output/components/select.js +97 -0
- package/output/components/spinner.d.ts +15 -0
- package/output/components/spinner.js +110 -0
- package/output/components/start.d.ts +2 -0
- package/output/components/start.js +33 -0
- package/output/components/text.d.ts +3 -0
- package/output/components/text.js +88 -0
- package/output/hooks/useKeyPress.d.ts +4 -0
- package/output/hooks/useKeyPress.js +14 -0
- package/output/main.d.ts +16 -0
- package/output/main.js +16 -0
- package/output/types/prod.d.ts +83 -0
- package/output/types/prod.js +0 -0
- package/output/utils/colorize.d.ts +2 -0
- package/output/utils/colorize.js +129 -0
- package/output/utils/errors.d.ts +1 -0
- package/output/utils/errors.js +11 -0
- package/output/utils/mapping.d.ts +4 -0
- package/output/utils/mapping.js +49 -0
- package/output/utils/messages.d.ts +17 -0
- package/output/utils/messages.js +203 -0
- package/output/utils/platforms.d.ts +1 -0
- package/output/utils/platforms.js +22 -0
- package/output/utils/prompt-tmp.d.ts +13 -0
- package/output/utils/prompt-tmp.js +254 -0
- package/output/utils/prompt.d.ts +13 -0
- package/output/utils/prompt.js +254 -0
- package/output/utils/readline.d.ts +2 -0
- package/output/utils/readline.js +9 -0
- package/output/utils/terminal.d.ts +5 -0
- package/output/utils/terminal.js +33 -0
- package/output/utils/variants.d.ts +9 -0
- package/output/utils/variants.js +49 -0
- package/package.json +96 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Value } from "@sinclair/typebox/value";
|
|
2
|
+
import { stdout } from "node:process";
|
|
3
|
+
import color from "picocolors";
|
|
4
|
+
import { useKeyPress } from "../hooks/useKeyPress";
|
|
5
|
+
import { colorize } from "../utils/colorize";
|
|
6
|
+
import { resetCursorAndClear, moveCursorAndClear } from "../utils/readline";
|
|
7
|
+
export async function selectPrompt(options) {
|
|
8
|
+
const {
|
|
9
|
+
title,
|
|
10
|
+
choices,
|
|
11
|
+
defaultValue,
|
|
12
|
+
schema,
|
|
13
|
+
titleColor = "cyanBright",
|
|
14
|
+
answerColor = "none",
|
|
15
|
+
titleTypography = "bold"
|
|
16
|
+
} = options;
|
|
17
|
+
if (schema) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
"Schema providing is currently not supported for selectPrompt().\n\u2502 But don't worry, we're already handling some validations for you."
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
if (!choices || choices.length === 0) {
|
|
23
|
+
throw new Error("Choices are required for select prompt.");
|
|
24
|
+
}
|
|
25
|
+
const coloredTitle = colorize(title, titleColor, titleTypography);
|
|
26
|
+
let selectedIndex = defaultValue !== void 0 ? choices.findIndex(
|
|
27
|
+
(choice, index) => choice.id === defaultValue || index + 1 === Number(defaultValue)
|
|
28
|
+
) : 0;
|
|
29
|
+
if (selectedIndex === -1) selectedIndex = 0;
|
|
30
|
+
function renderChoices() {
|
|
31
|
+
if (!choices) {
|
|
32
|
+
throw new Error("Choices are required for select prompt.");
|
|
33
|
+
}
|
|
34
|
+
resetCursorAndClear(stdout, 0, 0);
|
|
35
|
+
console.log(color.cyanBright(color.bold(coloredTitle)));
|
|
36
|
+
choices.forEach((choice, index) => {
|
|
37
|
+
const isSelected = index === selectedIndex;
|
|
38
|
+
const prefix = isSelected ? color.greenBright(">") : " ";
|
|
39
|
+
const choiceText = isSelected ? color.bgGreen(color.black(choice.title)) : choice.title;
|
|
40
|
+
console.log(`${prefix} ${choiceText}`);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
renderChoices();
|
|
44
|
+
return new Promise((resolve, reject) => {
|
|
45
|
+
const finalizeSelection = () => {
|
|
46
|
+
cleanupKeyPress();
|
|
47
|
+
moveCursorAndClear(stdout, 0, choices.length + 2);
|
|
48
|
+
const selectedChoice = choices[selectedIndex];
|
|
49
|
+
const selectedValue = selectedChoice?.id;
|
|
50
|
+
let isValid = true;
|
|
51
|
+
let errorMessage = "Invalid input.";
|
|
52
|
+
if (schema) {
|
|
53
|
+
try {
|
|
54
|
+
isValid = Value.Check(schema, selectedValue);
|
|
55
|
+
} catch (error) {
|
|
56
|
+
isValid = false;
|
|
57
|
+
errorMessage = "Validation error.";
|
|
58
|
+
console.error(error);
|
|
59
|
+
}
|
|
60
|
+
if (!isValid) {
|
|
61
|
+
const errors = [...Value.Errors(schema, selectedValue)];
|
|
62
|
+
if (errors.length > 0) {
|
|
63
|
+
errorMessage = errors[0]?.message ?? "Invalid input.";
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (isValid) {
|
|
68
|
+
if (selectedChoice?.action) {
|
|
69
|
+
selectedChoice.action().then(() => resolve(selectedValue ?? "")).catch(reject);
|
|
70
|
+
} else {
|
|
71
|
+
resolve(selectedValue ?? "");
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
console.log(errorMessage);
|
|
75
|
+
renderChoices();
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const handleKeyPress = (str, key) => {
|
|
79
|
+
if (key.name === "up") {
|
|
80
|
+
selectedIndex = (selectedIndex - 1 + choices.length) % choices.length;
|
|
81
|
+
renderChoices();
|
|
82
|
+
} else if (key.name === "down") {
|
|
83
|
+
selectedIndex = (selectedIndex + 1) % choices.length;
|
|
84
|
+
renderChoices();
|
|
85
|
+
} else if (key.name === "return") {
|
|
86
|
+
finalizeSelection();
|
|
87
|
+
} else if (key.ctrl && key.name === "c") {
|
|
88
|
+
cleanupKeyPress();
|
|
89
|
+
process.exit();
|
|
90
|
+
} else if (!isNaN(Number(str)) && Number(str) >= 1 && Number(str) <= choices.length) {
|
|
91
|
+
selectedIndex = Number(str) - 1;
|
|
92
|
+
finalizeSelection();
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
const cleanupKeyPress = useKeyPress(handleKeyPress);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type SpinnerName } from "cli-spinners";
|
|
2
|
+
type SimpleSpinnerType = "default" | "dottedCircle" | "boxSpinner";
|
|
3
|
+
type OraAllowedSpinners = "dots" | "bouncingBar" | "arc";
|
|
4
|
+
type OraSpinnerType = Extract<SpinnerName, OraAllowedSpinners>;
|
|
5
|
+
type CreateSpinnerOptions<T extends "simple" | "ora"> = {
|
|
6
|
+
initialMessage: string;
|
|
7
|
+
successMessage?: string;
|
|
8
|
+
errorMessage?: string;
|
|
9
|
+
delay?: number;
|
|
10
|
+
spinnerSolution: T;
|
|
11
|
+
spinnerType?: T extends "simple" ? SimpleSpinnerType : OraSpinnerType;
|
|
12
|
+
action: (updateMessage: (message: string) => void) => Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
export declare function spinnerPrompts<T extends "simple" | "ora">(options: CreateSpinnerOptions<T>): Promise<void>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import ora from "ora";
|
|
3
|
+
import color from "picocolors";
|
|
4
|
+
import { cursor, erase } from "sisteransi";
|
|
5
|
+
import { msg } from "../utils/messages";
|
|
6
|
+
export async function spinnerPrompts(options) {
|
|
7
|
+
const {
|
|
8
|
+
initialMessage,
|
|
9
|
+
successMessage = "Task completed successfully.",
|
|
10
|
+
errorMessage = "An error occurred during the task.",
|
|
11
|
+
delay = 100,
|
|
12
|
+
spinnerSolution,
|
|
13
|
+
spinnerType,
|
|
14
|
+
action
|
|
15
|
+
} = options;
|
|
16
|
+
let message = initialMessage;
|
|
17
|
+
let interval = null;
|
|
18
|
+
let frameIndex = 0;
|
|
19
|
+
if (spinnerSolution === "ora") {
|
|
20
|
+
const oraSpinner = ora({
|
|
21
|
+
text: initialMessage,
|
|
22
|
+
spinner: spinnerType
|
|
23
|
+
});
|
|
24
|
+
try {
|
|
25
|
+
oraSpinner.start();
|
|
26
|
+
await action((newMessage) => {
|
|
27
|
+
message = newMessage;
|
|
28
|
+
oraSpinner.text = newMessage;
|
|
29
|
+
});
|
|
30
|
+
oraSpinner.stop();
|
|
31
|
+
msg({
|
|
32
|
+
type: "M_INFO",
|
|
33
|
+
title: successMessage,
|
|
34
|
+
titleColor: "green"
|
|
35
|
+
});
|
|
36
|
+
} catch (error) {
|
|
37
|
+
oraSpinner.stopAndPersist({
|
|
38
|
+
symbol: color.red("\u2716"),
|
|
39
|
+
text: errorMessage
|
|
40
|
+
});
|
|
41
|
+
msg({
|
|
42
|
+
type: "M_ERROR",
|
|
43
|
+
title: error instanceof Error ? error.message : "An unknown error occurred.",
|
|
44
|
+
titleColor: "red"
|
|
45
|
+
});
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
const simpleSpinners = {
|
|
50
|
+
default: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"],
|
|
51
|
+
dottedCircle: ["\u25CB", "\u25D4", "\u25D1", "\u25D5", "\u25CF"],
|
|
52
|
+
boxSpinner: ["\u2596", "\u2598", "\u259D", "\u2597"]
|
|
53
|
+
};
|
|
54
|
+
const frames = spinnerType && spinnerType in simpleSpinners ? simpleSpinners[spinnerType] : simpleSpinners.default;
|
|
55
|
+
const handleInput = (data) => {
|
|
56
|
+
const key = data.toString();
|
|
57
|
+
if (key === "\r" || key === "\n") {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
try {
|
|
62
|
+
if (process.stdin.isTTY && typeof process.stdin.setRawMode === "function") {
|
|
63
|
+
process.stdin.setRawMode(true);
|
|
64
|
+
process.stdin.resume();
|
|
65
|
+
process.stdin.on("data", handleInput);
|
|
66
|
+
}
|
|
67
|
+
interval = setInterval(() => {
|
|
68
|
+
const frame = color.magenta(frames[frameIndex]);
|
|
69
|
+
process.stdout.write(
|
|
70
|
+
`${cursor.move(-999, 0)}${erase.line}${frame} ${color.cyan(message)}`
|
|
71
|
+
);
|
|
72
|
+
frameIndex = (frameIndex + 1) % frames.length;
|
|
73
|
+
}, delay);
|
|
74
|
+
await action((newMessage) => {
|
|
75
|
+
message = newMessage;
|
|
76
|
+
});
|
|
77
|
+
clearInterval(interval);
|
|
78
|
+
interval = null;
|
|
79
|
+
process.stdout.write(
|
|
80
|
+
`\r${erase.line}${color.green("\u2714")} ${successMessage}
|
|
81
|
+
`
|
|
82
|
+
);
|
|
83
|
+
msg({
|
|
84
|
+
type: "M_INFO",
|
|
85
|
+
title: successMessage,
|
|
86
|
+
titleColor: "green"
|
|
87
|
+
});
|
|
88
|
+
} catch (error) {
|
|
89
|
+
if (interval) {
|
|
90
|
+
clearInterval(interval);
|
|
91
|
+
}
|
|
92
|
+
process.stdout.write(
|
|
93
|
+
`\r${erase.line}${color.red("\u2716")} ${error instanceof Error ? errorMessage : "An unknown error occurred."}
|
|
94
|
+
`
|
|
95
|
+
);
|
|
96
|
+
msg({
|
|
97
|
+
type: "M_ERROR",
|
|
98
|
+
title: error instanceof Error ? error.message : "An unknown error occurred.",
|
|
99
|
+
titleColor: "red"
|
|
100
|
+
});
|
|
101
|
+
process.exit(1);
|
|
102
|
+
} finally {
|
|
103
|
+
if (process.stdin.isTTY && typeof process.stdin.setRawMode === "function") {
|
|
104
|
+
process.stdin.setRawMode(false);
|
|
105
|
+
process.stdin.pause();
|
|
106
|
+
process.stdin.removeListener("data", handleInput);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { msg } from "../utils/messages";
|
|
2
|
+
export async function startPrompt({
|
|
3
|
+
title,
|
|
4
|
+
titleColor = "cyanBright",
|
|
5
|
+
answerColor = "none",
|
|
6
|
+
titleTypography = "bold",
|
|
7
|
+
titleVariant,
|
|
8
|
+
borderColor = "viceGradient",
|
|
9
|
+
clearConsole = true
|
|
10
|
+
}) {
|
|
11
|
+
if (clearConsole) {
|
|
12
|
+
console.clear();
|
|
13
|
+
console.log();
|
|
14
|
+
} else {
|
|
15
|
+
console.log();
|
|
16
|
+
}
|
|
17
|
+
msg({
|
|
18
|
+
type: "M_START",
|
|
19
|
+
title: ` ${title} `,
|
|
20
|
+
titleColor,
|
|
21
|
+
titleTypography,
|
|
22
|
+
titleVariant,
|
|
23
|
+
borderColor
|
|
24
|
+
});
|
|
25
|
+
if (!process.stdout.isTTY) {
|
|
26
|
+
console.error(
|
|
27
|
+
"\u2502 Your terminal does not support cursor manipulations.\n\u2502 It's recommended to use a terminal which supports TTY."
|
|
28
|
+
);
|
|
29
|
+
msg({
|
|
30
|
+
type: "M_NEWLINE"
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { Value } from "@sinclair/typebox/value";
|
|
2
|
+
import { stdin as input, stdout as output } from "node:process";
|
|
3
|
+
import readline from "node:readline/promises";
|
|
4
|
+
import { fmt, msg } from "../utils/messages";
|
|
5
|
+
import { countLines, deleteLastLine, deleteLastLines } from "../utils/terminal";
|
|
6
|
+
export async function textPrompt(options) {
|
|
7
|
+
const {
|
|
8
|
+
title,
|
|
9
|
+
hint,
|
|
10
|
+
validate,
|
|
11
|
+
defaultValue = "",
|
|
12
|
+
schema,
|
|
13
|
+
titleColor = "cyanBright",
|
|
14
|
+
answerColor = "none",
|
|
15
|
+
titleTypography = "bold",
|
|
16
|
+
titleVariant,
|
|
17
|
+
content,
|
|
18
|
+
contentColor,
|
|
19
|
+
contentTypography,
|
|
20
|
+
contentVariant,
|
|
21
|
+
borderColor = "viceGradient",
|
|
22
|
+
variantOptions
|
|
23
|
+
} = options;
|
|
24
|
+
const rl = readline.createInterface({ input, output });
|
|
25
|
+
let linesToDelete = 0;
|
|
26
|
+
let errorMessage = "";
|
|
27
|
+
while (true) {
|
|
28
|
+
if (linesToDelete > 0) {
|
|
29
|
+
deleteLastLines(linesToDelete);
|
|
30
|
+
}
|
|
31
|
+
const question = fmt({
|
|
32
|
+
type: errorMessage !== "" ? "M_ERROR" : "M_GENERAL",
|
|
33
|
+
title,
|
|
34
|
+
titleColor,
|
|
35
|
+
titleTypography,
|
|
36
|
+
titleVariant,
|
|
37
|
+
content,
|
|
38
|
+
contentColor,
|
|
39
|
+
contentTypography,
|
|
40
|
+
contentVariant,
|
|
41
|
+
borderColor,
|
|
42
|
+
hint,
|
|
43
|
+
variantOptions,
|
|
44
|
+
errorMessage
|
|
45
|
+
});
|
|
46
|
+
const questionLines = countLines(question);
|
|
47
|
+
const prompt = await rl.question(question);
|
|
48
|
+
linesToDelete = questionLines + 1;
|
|
49
|
+
const answer = prompt.trim() || defaultValue;
|
|
50
|
+
if (prompt.trim() === "" && defaultValue !== "") {
|
|
51
|
+
deleteLastLine();
|
|
52
|
+
const defaultMsg = fmt({
|
|
53
|
+
type: "M_MIDDLE",
|
|
54
|
+
title: ` ${defaultValue}`,
|
|
55
|
+
borderColor
|
|
56
|
+
});
|
|
57
|
+
console.log(defaultMsg);
|
|
58
|
+
linesToDelete += countLines(defaultMsg);
|
|
59
|
+
}
|
|
60
|
+
let isValid = true;
|
|
61
|
+
errorMessage = "";
|
|
62
|
+
if (schema) {
|
|
63
|
+
isValid = Value.Check(schema, answer);
|
|
64
|
+
if (!isValid) {
|
|
65
|
+
const errors = [...Value.Errors(schema, answer)];
|
|
66
|
+
if (errors.length > 0) {
|
|
67
|
+
errorMessage = errors[0]?.message ?? "Invalid input.";
|
|
68
|
+
} else {
|
|
69
|
+
errorMessage = "Invalid input.";
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (validate && isValid) {
|
|
74
|
+
const validation = await validate(answer);
|
|
75
|
+
if (validation !== true) {
|
|
76
|
+
isValid = false;
|
|
77
|
+
errorMessage = typeof validation === "string" ? validation : "Invalid input.";
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (isValid) {
|
|
81
|
+
msg({ type: "M_NEWLINE" });
|
|
82
|
+
rl.close();
|
|
83
|
+
return answer;
|
|
84
|
+
} else {
|
|
85
|
+
linesToDelete += 0;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { stdin } from "node:process";
|
|
2
|
+
import readline from "node:readline";
|
|
3
|
+
export function useKeyPress(callback) {
|
|
4
|
+
readline.emitKeypressEvents(stdin);
|
|
5
|
+
if (stdin.isTTY) stdin.setRawMode(true);
|
|
6
|
+
const onKeypress = (str, key) => {
|
|
7
|
+
callback(str, key);
|
|
8
|
+
};
|
|
9
|
+
stdin.on("keypress", onKeypress);
|
|
10
|
+
return () => {
|
|
11
|
+
stdin.setRawMode(false);
|
|
12
|
+
stdin.off("keypress", onKeypress);
|
|
13
|
+
};
|
|
14
|
+
}
|
package/output/main.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { colorize } from "./utils/colorize";
|
|
2
|
+
export { msg, fmt } from "./utils/messages";
|
|
3
|
+
export { animateText } from "./components/animate";
|
|
4
|
+
export { createAsciiArt } from "./components/ascii-art";
|
|
5
|
+
export { spinnerPrompts } from "./components/spinner";
|
|
6
|
+
export { startPrompt } from "./components/start";
|
|
7
|
+
export { textPrompt } from "./components/text";
|
|
8
|
+
export { selectPrompt } from "./components/select";
|
|
9
|
+
export { confirmPrompt } from "./components/confirm";
|
|
10
|
+
export { datePrompt } from "./components/date";
|
|
11
|
+
export { numMultiSelectPrompt } from "./components/num-multi-select";
|
|
12
|
+
export { nextStepsPrompt } from "./components/next-steps";
|
|
13
|
+
export { numberPrompt } from "./components/number";
|
|
14
|
+
export { passwordPrompt } from "./components/password";
|
|
15
|
+
export { endPrompt } from "./components/end";
|
|
16
|
+
export { prompt } from "./components/mono";
|
package/output/main.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { colorize } from "./utils/colorize";
|
|
2
|
+
export { msg, fmt } from "./utils/messages";
|
|
3
|
+
export { animateText } from "./components/animate";
|
|
4
|
+
export { createAsciiArt } from "./components/ascii-art";
|
|
5
|
+
export { spinnerPrompts } from "./components/spinner";
|
|
6
|
+
export { startPrompt } from "./components/start";
|
|
7
|
+
export { textPrompt } from "./components/text";
|
|
8
|
+
export { selectPrompt } from "./components/select";
|
|
9
|
+
export { confirmPrompt } from "./components/confirm";
|
|
10
|
+
export { datePrompt } from "./components/date";
|
|
11
|
+
export { numMultiSelectPrompt } from "./components/num-multi-select";
|
|
12
|
+
export { nextStepsPrompt } from "./components/next-steps";
|
|
13
|
+
export { numberPrompt } from "./components/number";
|
|
14
|
+
export { passwordPrompt } from "./components/password";
|
|
15
|
+
export { endPrompt } from "./components/end";
|
|
16
|
+
export { prompt } from "./components/mono";
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { AnimationName } from "@figliolia/chalk-animation";
|
|
2
|
+
import type { TSchema } from "@sinclair/typebox";
|
|
3
|
+
export type MsgType = "M_NULL" | "M_START" | "M_MIDDLE" | "M_GENERAL" | "M_INFO" | "M_NEWLINE" | "M_END" | "M_END_ANIMATED" | "M_ERROR";
|
|
4
|
+
export type TypographyName = "bold" | "strikethrough" | "underline" | "italic";
|
|
5
|
+
export type Variant = "box" | "doubleBox" | "banner" | "underline" | "none" | "animated";
|
|
6
|
+
export type ColorName = "dim" | "inverse" | "black" | "red" | "redBright" | "bgRed" | "bgRedBright" | "green" | "greenBright" | "bgGreen" | "bgGreenBright" | "yellow" | "yellowBright" | "blue" | "blueBright" | "magenta" | "cyan" | "cyanBright" | "bgCyan" | "bgCyanBright" | "white" | "gray" | "gradientGradient" | "rainbowGradient" | "cristalGradient" | "mindGradient" | "passionGradient" | "viceGradient" | "retroGradient" | "none";
|
|
7
|
+
export type MsgConfig = {
|
|
8
|
+
symbol: string;
|
|
9
|
+
prefix?: string;
|
|
10
|
+
color?: (text: string) => string;
|
|
11
|
+
newLineBefore?: boolean;
|
|
12
|
+
newLineAfter?: boolean;
|
|
13
|
+
suffix?: string;
|
|
14
|
+
};
|
|
15
|
+
export type FmtMsgOptions = {
|
|
16
|
+
type: MsgType;
|
|
17
|
+
title?: string;
|
|
18
|
+
titleAfterAnim?: string;
|
|
19
|
+
content?: string;
|
|
20
|
+
titleColor?: ColorName;
|
|
21
|
+
titleTypography?: TypographyName;
|
|
22
|
+
titleVariant?: Variant;
|
|
23
|
+
contentColor?: ColorName;
|
|
24
|
+
contentTypography?: TypographyName;
|
|
25
|
+
contentVariant?: Variant;
|
|
26
|
+
hint?: string;
|
|
27
|
+
border?: boolean;
|
|
28
|
+
borderColor?: ColorName;
|
|
29
|
+
variantOptions?: {
|
|
30
|
+
box?: {
|
|
31
|
+
limit?: number;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
errorMessage?: string;
|
|
35
|
+
addNewLineBefore?: boolean;
|
|
36
|
+
addNewLineAfter?: boolean;
|
|
37
|
+
};
|
|
38
|
+
export type RequiredPromptOptions = {
|
|
39
|
+
id: string;
|
|
40
|
+
title: string;
|
|
41
|
+
};
|
|
42
|
+
export type OptionalPromptOptions<T extends TSchema = any> = {
|
|
43
|
+
schema?: T;
|
|
44
|
+
titleColor?: ColorName;
|
|
45
|
+
titleTypography?: TypographyName;
|
|
46
|
+
titleVariant?: Variant;
|
|
47
|
+
titleAnimation?: AnimationName;
|
|
48
|
+
titleAnimationDelay?: number;
|
|
49
|
+
content?: string;
|
|
50
|
+
contentColor?: ColorName;
|
|
51
|
+
contentTypography?: TypographyName;
|
|
52
|
+
contentVariant?: Variant;
|
|
53
|
+
hint?: string;
|
|
54
|
+
validate?: (value: any) => boolean | string | Promise<boolean | string>;
|
|
55
|
+
defaultValue?: string | string[] | number | boolean;
|
|
56
|
+
defaultColor?: ColorName;
|
|
57
|
+
defaultTypography?: TypographyName;
|
|
58
|
+
choices?: ChoiceOptions[];
|
|
59
|
+
variantOptions?: {
|
|
60
|
+
box?: {
|
|
61
|
+
limit?: number;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
action?: () => Promise<void>;
|
|
65
|
+
border?: boolean;
|
|
66
|
+
borderColor?: ColorName;
|
|
67
|
+
clearConsole?: boolean;
|
|
68
|
+
additionalLinesToDelete?: number;
|
|
69
|
+
answerColor?: ColorName;
|
|
70
|
+
hintColor?: ColorName;
|
|
71
|
+
};
|
|
72
|
+
export type PromptOptions<T extends TSchema = any> = RequiredPromptOptions & OptionalPromptOptions<T>;
|
|
73
|
+
export type ChoiceRequiredOptions = {
|
|
74
|
+
id: string;
|
|
75
|
+
title: string;
|
|
76
|
+
};
|
|
77
|
+
export type ChoiceOptionalOptions = {
|
|
78
|
+
description?: string;
|
|
79
|
+
titleTypography?: TypographyName;
|
|
80
|
+
action?: () => Promise<void>;
|
|
81
|
+
};
|
|
82
|
+
export type ChoiceOptions = ChoiceRequiredOptions & ChoiceOptionalOptions;
|
|
83
|
+
export type PromptType = "text" | "number" | "confirm" | "numSelect" | "select" | "multiselect" | "password" | "date" | "start" | "nextSteps" | "end";
|
|
File without changes
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import gradient, {
|
|
2
|
+
cristal,
|
|
3
|
+
mind,
|
|
4
|
+
passion,
|
|
5
|
+
rainbow,
|
|
6
|
+
vice
|
|
7
|
+
} from "gradient-string";
|
|
8
|
+
import {
|
|
9
|
+
red,
|
|
10
|
+
inverse,
|
|
11
|
+
dim,
|
|
12
|
+
black,
|
|
13
|
+
green,
|
|
14
|
+
yellow,
|
|
15
|
+
blue,
|
|
16
|
+
magenta,
|
|
17
|
+
cyan,
|
|
18
|
+
cyanBright,
|
|
19
|
+
bgCyan,
|
|
20
|
+
bgCyanBright,
|
|
21
|
+
white,
|
|
22
|
+
gray,
|
|
23
|
+
underline,
|
|
24
|
+
bold,
|
|
25
|
+
strikethrough,
|
|
26
|
+
italic
|
|
27
|
+
} from "picocolors";
|
|
28
|
+
export function colorize(text, colorName, typography) {
|
|
29
|
+
let result = text;
|
|
30
|
+
switch (colorName) {
|
|
31
|
+
case "inverse":
|
|
32
|
+
result = inverse(` ${result} `);
|
|
33
|
+
break;
|
|
34
|
+
case "dim":
|
|
35
|
+
result = dim(result);
|
|
36
|
+
break;
|
|
37
|
+
case "black":
|
|
38
|
+
result = black(result);
|
|
39
|
+
break;
|
|
40
|
+
case "red":
|
|
41
|
+
result = red(result);
|
|
42
|
+
break;
|
|
43
|
+
case "green":
|
|
44
|
+
result = green(result);
|
|
45
|
+
break;
|
|
46
|
+
case "yellow":
|
|
47
|
+
result = yellow(result);
|
|
48
|
+
break;
|
|
49
|
+
case "blue":
|
|
50
|
+
result = blue(result);
|
|
51
|
+
break;
|
|
52
|
+
case "magenta":
|
|
53
|
+
result = magenta(result);
|
|
54
|
+
break;
|
|
55
|
+
case "cyan":
|
|
56
|
+
result = cyan(result);
|
|
57
|
+
break;
|
|
58
|
+
case "cyanBright":
|
|
59
|
+
result = cyanBright(result);
|
|
60
|
+
break;
|
|
61
|
+
case "bgCyan":
|
|
62
|
+
result = bgCyan(` ${result} `);
|
|
63
|
+
break;
|
|
64
|
+
case "bgCyanBright":
|
|
65
|
+
result = bgCyanBright(` ${result} `);
|
|
66
|
+
break;
|
|
67
|
+
case "white":
|
|
68
|
+
result = white(result);
|
|
69
|
+
break;
|
|
70
|
+
case "gray":
|
|
71
|
+
result = gray(result);
|
|
72
|
+
break;
|
|
73
|
+
case "gradientGradient":
|
|
74
|
+
result = gradient(["red", "yellow", "green", "cyan", "blue", "magenta"])(
|
|
75
|
+
result
|
|
76
|
+
);
|
|
77
|
+
break;
|
|
78
|
+
case "rainbowGradient":
|
|
79
|
+
result = rainbow(result);
|
|
80
|
+
break;
|
|
81
|
+
case "cristalGradient":
|
|
82
|
+
result = cristal(result);
|
|
83
|
+
break;
|
|
84
|
+
case "mindGradient":
|
|
85
|
+
result = mind(result);
|
|
86
|
+
break;
|
|
87
|
+
case "passionGradient":
|
|
88
|
+
result = passion(result);
|
|
89
|
+
break;
|
|
90
|
+
case "viceGradient":
|
|
91
|
+
result = vice(result);
|
|
92
|
+
break;
|
|
93
|
+
case "none":
|
|
94
|
+
break;
|
|
95
|
+
default:
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
const gradientColors = [
|
|
99
|
+
"gradientGradient",
|
|
100
|
+
"cristalGradient",
|
|
101
|
+
"mindGradient",
|
|
102
|
+
"passionGradient",
|
|
103
|
+
"rainbowGradient",
|
|
104
|
+
"viceGradient"
|
|
105
|
+
];
|
|
106
|
+
if (gradientColors.includes(colorName ?? "") && typography)
|
|
107
|
+
throw new Error(
|
|
108
|
+
"[colorize] Cannot apply typography to gradient color.\n\u2502 Use regular colorize()'s color or remove typography."
|
|
109
|
+
);
|
|
110
|
+
if (!gradientColors.includes(colorName ?? "") && typography) {
|
|
111
|
+
switch (typography) {
|
|
112
|
+
case "bold":
|
|
113
|
+
result = bold(result);
|
|
114
|
+
break;
|
|
115
|
+
case "strikethrough":
|
|
116
|
+
result = strikethrough(result);
|
|
117
|
+
break;
|
|
118
|
+
case "underline":
|
|
119
|
+
result = underline(result);
|
|
120
|
+
break;
|
|
121
|
+
case "italic":
|
|
122
|
+
result = italic(result);
|
|
123
|
+
break;
|
|
124
|
+
default:
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const errorHandler: (error: Error) => never;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const errorHandler = (error) => {
|
|
2
|
+
const separator = "\u2500".repeat(71);
|
|
3
|
+
console.error("\u2502" + separator);
|
|
4
|
+
console.error("\u2502 AN ERROR OCCURRED:\n\u2502 ", error.message);
|
|
5
|
+
console.error("\u2502" + separator);
|
|
6
|
+
console.error(
|
|
7
|
+
"\u2502 If this issue is related to @reliverse/relinka itself, please\n\u2502 report the details at https://github.com/reliverse/prompts/issues"
|
|
8
|
+
);
|
|
9
|
+
console.error("\u2570" + separator);
|
|
10
|
+
process.exit(1);
|
|
11
|
+
};
|