@reliverse/rempts 1.7.52 → 1.7.53

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.
Files changed (105) hide show
  1. package/bin/libs/animate/animate-mod.d.ts +14 -0
  2. package/bin/libs/animate/animate-mod.js +60 -0
  3. package/bin/libs/anykey/anykey-mod.d.ts +12 -0
  4. package/bin/libs/anykey/anykey-mod.js +125 -0
  5. package/bin/libs/cancel/cancel.d.ts +45 -0
  6. package/bin/libs/cancel/cancel.js +72 -0
  7. package/bin/libs/confirm/confirm-alias.d.ts +2 -0
  8. package/bin/libs/confirm/confirm-alias.js +2 -0
  9. package/bin/libs/confirm/confirm-mod.d.ts +5 -0
  10. package/bin/libs/confirm/confirm-mod.js +179 -0
  11. package/bin/libs/date/date.d.ts +2 -0
  12. package/bin/libs/date/date.js +214 -0
  13. package/bin/libs/editor/editor-mod.d.ts +25 -0
  14. package/bin/libs/editor/editor-mod.js +1133 -0
  15. package/bin/libs/figures/figures-mod.d.ts +461 -0
  16. package/bin/libs/figures/figures-mod.js +285 -0
  17. package/bin/libs/group/group-mod.d.ts +33 -0
  18. package/bin/libs/group/group-mod.js +89 -0
  19. package/bin/libs/input/input-alias.d.ts +5 -0
  20. package/bin/libs/input/input-alias.js +4 -0
  21. package/bin/libs/input/input-mod.d.ts +16 -0
  22. package/bin/libs/input/input-mod.js +372 -0
  23. package/bin/libs/intro/intro-alias.d.ts +3 -0
  24. package/bin/libs/intro/intro-alias.js +3 -0
  25. package/bin/libs/intro/intro-mod.d.ts +20 -0
  26. package/bin/libs/intro/intro-mod.js +77 -0
  27. package/bin/libs/launcher/command-runner.d.ts +31 -0
  28. package/bin/libs/launcher/command-runner.js +229 -0
  29. package/bin/libs/launcher/launcher-alias.d.ts +2 -0
  30. package/bin/libs/launcher/launcher-alias.js +2 -0
  31. package/bin/libs/launcher/launcher-mod.d.ts +66 -0
  32. package/bin/libs/launcher/launcher-mod.js +975 -0
  33. package/bin/libs/launcher/launcher-types.d.ts +176 -0
  34. package/bin/libs/launcher/launcher-types.js +0 -0
  35. package/bin/libs/log/log-alias.d.ts +1 -0
  36. package/bin/libs/log/log-alias.js +2 -0
  37. package/bin/libs/msg-fmt/colors.d.ts +30 -0
  38. package/bin/libs/msg-fmt/colors.js +42 -0
  39. package/bin/libs/msg-fmt/logger.d.ts +17 -0
  40. package/bin/libs/msg-fmt/logger.js +103 -0
  41. package/bin/libs/msg-fmt/mapping.d.ts +3 -0
  42. package/bin/libs/msg-fmt/mapping.js +41 -0
  43. package/bin/libs/msg-fmt/messages.d.ts +35 -0
  44. package/bin/libs/msg-fmt/messages.js +305 -0
  45. package/bin/libs/msg-fmt/terminal.d.ts +15 -0
  46. package/bin/libs/msg-fmt/terminal.js +60 -0
  47. package/bin/libs/msg-fmt/variants.d.ts +11 -0
  48. package/bin/libs/msg-fmt/variants.js +52 -0
  49. package/bin/libs/multiselect/multiselect-alias.d.ts +2 -0
  50. package/bin/libs/multiselect/multiselect-alias.js +2 -0
  51. package/bin/libs/multiselect/multiselect-prompt.d.ts +2 -0
  52. package/bin/libs/multiselect/multiselect-prompt.js +340 -0
  53. package/bin/libs/next-steps/next-steps.d.ts +13 -0
  54. package/bin/libs/next-steps/next-steps.js +24 -0
  55. package/bin/libs/number/number-mod.d.ts +28 -0
  56. package/bin/libs/number/number-mod.js +194 -0
  57. package/bin/libs/outro/outro-alias.d.ts +3 -0
  58. package/bin/libs/outro/outro-alias.js +3 -0
  59. package/bin/libs/outro/outro-mod.d.ts +8 -0
  60. package/bin/libs/outro/outro-mod.js +55 -0
  61. package/bin/libs/reliarg/reliarg-mod.d.ts +76 -0
  62. package/bin/libs/reliarg/reliarg-mod.js +276 -0
  63. package/bin/libs/results/results.d.ts +7 -0
  64. package/bin/libs/results/results.js +27 -0
  65. package/bin/libs/select/nummultiselect-prompt.d.ts +6 -0
  66. package/bin/libs/select/nummultiselect-prompt.js +101 -0
  67. package/bin/libs/select/numselect-prompt.d.ts +7 -0
  68. package/bin/libs/select/numselect-prompt.js +111 -0
  69. package/bin/libs/select/select-alias.d.ts +9 -0
  70. package/bin/libs/select/select-alias.js +9 -0
  71. package/bin/libs/select/select-prompt.d.ts +5 -0
  72. package/bin/libs/select/select-prompt.js +308 -0
  73. package/bin/libs/select/toggle-prompt.d.ts +5 -0
  74. package/bin/libs/select/toggle-prompt.js +207 -0
  75. package/bin/libs/spinner/spinner-alias.d.ts +2 -0
  76. package/bin/libs/spinner/spinner-alias.js +2 -0
  77. package/bin/libs/spinner/spinner-mod.d.ts +106 -0
  78. package/bin/libs/spinner/spinner-mod.js +255 -0
  79. package/bin/libs/task/progress.d.ts +2 -0
  80. package/bin/libs/task/progress.js +57 -0
  81. package/bin/libs/task/task-spin.d.ts +15 -0
  82. package/bin/libs/task/task-spin.js +106 -0
  83. package/bin/libs/utils/colorize.d.ts +2 -0
  84. package/bin/libs/utils/colorize.js +122 -0
  85. package/bin/libs/utils/errors.d.ts +1 -0
  86. package/bin/libs/utils/errors.js +17 -0
  87. package/bin/libs/utils/prevent.d.ts +8 -0
  88. package/bin/libs/utils/prevent.js +62 -0
  89. package/bin/libs/utils/prompt-end.d.ts +8 -0
  90. package/bin/libs/utils/prompt-end.js +34 -0
  91. package/bin/libs/utils/stream-text.d.ts +18 -0
  92. package/bin/libs/utils/stream-text.js +137 -0
  93. package/bin/libs/utils/system.d.ts +6 -0
  94. package/bin/libs/utils/system.js +7 -0
  95. package/bin/libs/utils/validate.d.ts +21 -0
  96. package/bin/libs/utils/validate.js +17 -0
  97. package/bin/libs/visual/visual-mod.d.ts +6 -0
  98. package/bin/libs/visual/visual-mod.js +13 -0
  99. package/bin/mod.d.ts +53 -0
  100. package/bin/mod.js +107 -0
  101. package/bin/types.d.ts +371 -0
  102. package/bin/types.js +0 -0
  103. package/package.json +34 -59
  104. package/dist-npm/bin/mod.d.mts +0 -1753
  105. package/dist-npm/bin/mod.mjs +0 -6779
@@ -0,0 +1,255 @@
1
+ import { re } from "@reliverse/relico";
2
+ import { block } from "../cancel/cancel.js";
3
+ const unicode = process.platform !== "win32" || process.env.TERM_PROGRAM === "vscode";
4
+ const defaultFrames = unicode ? ["\u25D2", "\u25D0", "\u25D3", "\u25D1"] : ["\u2022", "o", "O", "0"];
5
+ const defaultDelay = unicode ? 80 : 120;
6
+ function isInteractive() {
7
+ return process.stdout.isTTY && !process.env.CI && !process.env.GITHUB_ACTIONS && !process.env.GITLAB_CI && !process.env.BUILDKITE && process.env.TERM !== "dumb";
8
+ }
9
+ function formatProgress(options) {
10
+ const { current, total, format = "both" } = options;
11
+ const percentage = Math.round(current / total * 100);
12
+ switch (format) {
13
+ case "percentage":
14
+ return `${percentage}%`;
15
+ case "count":
16
+ return `${current}/${total}`;
17
+ case "both":
18
+ return `${current}/${total} (${percentage}%)`;
19
+ default:
20
+ return `${current}/${total}`;
21
+ }
22
+ }
23
+ function formatTimer(origin) {
24
+ const duration = (performance.now() - origin) / 1e3;
25
+ const min = Math.floor(duration / 60);
26
+ const secs = Math.floor(duration % 60);
27
+ return min > 0 ? `[${min}m ${secs}s]` : `[${secs}s]`;
28
+ }
29
+ function removeTrailingDots(msg) {
30
+ return msg.replace(/\.+$/, "");
31
+ }
32
+ export function useSpinner(options) {
33
+ let loop;
34
+ const interactive = isInteractive();
35
+ let unblock = null;
36
+ const state = {
37
+ isActive: false,
38
+ isPaused: false,
39
+ startTime: null,
40
+ pausedTime: 0,
41
+ text: options.text,
42
+ isCancelled: false,
43
+ origin: performance.now(),
44
+ indicatorTimer: 0
45
+ };
46
+ const handleExit = (code) => {
47
+ const msg = code > 1 ? options.errorMessage ?? "Operation failed" : options.cancelMessage ?? "Operation cancelled";
48
+ state.isCancelled = code === 1;
49
+ if (state.isActive) {
50
+ controls.stop(msg, code);
51
+ if (state.isCancelled && typeof options.onCancel === "function") {
52
+ options.onCancel();
53
+ }
54
+ }
55
+ };
56
+ const errorEventHandler = () => handleExit(2);
57
+ const signalEventHandler = () => handleExit(1);
58
+ const registerHooks = () => {
59
+ process.on("uncaughtExceptionMonitor", errorEventHandler);
60
+ process.on("unhandledRejection", errorEventHandler);
61
+ process.on("SIGINT", signalEventHandler);
62
+ process.on("SIGTERM", signalEventHandler);
63
+ process.on("exit", handleExit);
64
+ if (options.signal) {
65
+ options.signal.addEventListener("abort", signalEventHandler);
66
+ }
67
+ };
68
+ const clearHooks = () => {
69
+ process.removeListener("uncaughtExceptionMonitor", errorEventHandler);
70
+ process.removeListener("unhandledRejection", errorEventHandler);
71
+ process.removeListener("SIGINT", signalEventHandler);
72
+ process.removeListener("SIGTERM", signalEventHandler);
73
+ process.removeListener("exit", handleExit);
74
+ if (options.signal) {
75
+ options.signal.removeEventListener("abort", signalEventHandler);
76
+ }
77
+ };
78
+ const clearPrevMessage = () => {
79
+ if (state.prevMessage === void 0) return;
80
+ if (process.env.CI) process.stdout.write("\n");
81
+ const prevLines = state.prevMessage.split("\n");
82
+ process.stdout.write(`\x1B[${prevLines.length}A`);
83
+ process.stdout.write("\x1B[0J");
84
+ };
85
+ const controls = {
86
+ start: (text) => {
87
+ if (text) {
88
+ options.text = text;
89
+ state.text = text;
90
+ }
91
+ if (options.silent || !interactive) {
92
+ console.log(options.prefixText ? `${options.prefixText} ${options.text}` : options.text);
93
+ state.isActive = true;
94
+ state.startTime = Date.now();
95
+ return controls;
96
+ }
97
+ state.isActive = true;
98
+ state.origin = performance.now();
99
+ unblock = block({ output: process.stdout });
100
+ process.stdout.write(`${re.dim("\u2502")}
101
+ `);
102
+ let frameIndex = 0;
103
+ registerHooks();
104
+ loop = setInterval(() => {
105
+ if (process.env.CI && state.text === state.prevMessage) {
106
+ return;
107
+ }
108
+ clearPrevMessage();
109
+ state.prevMessage = state.text;
110
+ const frame = re.magenta((options.frames ?? defaultFrames)[frameIndex] ?? "");
111
+ if (process.env.CI) {
112
+ process.stdout.write(`${frame} ${state.text}...`);
113
+ } else if (options.indicator === "timer") {
114
+ process.stdout.write(`${frame} ${state.text} ${formatTimer(state.origin)}`);
115
+ } else {
116
+ const loadingDots = ".".repeat(Math.floor(state.indicatorTimer)).slice(0, 3);
117
+ process.stdout.write(`${frame} ${state.text}${loadingDots}`);
118
+ }
119
+ frameIndex = (frameIndex + 1) % (options.frames ?? defaultFrames).length;
120
+ state.indicatorTimer = state.indicatorTimer < 4 ? state.indicatorTimer + 0.125 : 0;
121
+ }, options.delay ?? defaultDelay);
122
+ return controls;
123
+ },
124
+ stop: (text, code = 0) => {
125
+ if (!state.isActive) return;
126
+ state.isActive = false;
127
+ clearInterval(loop);
128
+ clearPrevMessage();
129
+ const step = code === 0 ? re.green("\u2713") : code === 1 ? re.red("\u2717") : re.red("\u2717");
130
+ const finalText = text ?? state.text;
131
+ if (options.indicator === "timer") {
132
+ process.stdout.write(`${step} ${finalText} ${formatTimer(state.origin)}
133
+ `);
134
+ } else {
135
+ process.stdout.write(`${step} ${finalText}
136
+ `);
137
+ }
138
+ clearHooks();
139
+ if (unblock) unblock();
140
+ },
141
+ setText: (text) => {
142
+ state.text = removeTrailingDots(text);
143
+ options.text = text;
144
+ },
145
+ setProgress: (progress) => {
146
+ const progressText = formatProgress(progress);
147
+ const newText = `${state.text} [${progressText}]`;
148
+ state.text = newText;
149
+ options.text = newText;
150
+ },
151
+ succeed: (text) => {
152
+ const successText = text ?? options.successText ?? state.text;
153
+ controls.stop(successText, 0);
154
+ },
155
+ fail: (text) => {
156
+ const failText = text ?? options.failText ?? state.text;
157
+ controls.stop(failText, 2);
158
+ },
159
+ warn: (text) => {
160
+ const warnText = text ?? state.text;
161
+ controls.stop(warnText, 0);
162
+ },
163
+ info: (text) => {
164
+ const infoText = text ?? state.text;
165
+ controls.stop(infoText, 0);
166
+ },
167
+ isSpinning: () => {
168
+ return state.isActive && !state.isPaused;
169
+ },
170
+ clear: () => {
171
+ clearPrevMessage();
172
+ },
173
+ getElapsedTime: () => {
174
+ if (!state.startTime) return 0;
175
+ const currentTime = Date.now();
176
+ return currentTime - state.startTime - state.pausedTime;
177
+ },
178
+ pause: () => {
179
+ if (state.isActive && !state.isPaused) {
180
+ clearInterval(loop);
181
+ state.isPaused = true;
182
+ }
183
+ },
184
+ resume: () => {
185
+ if (state.isActive && state.isPaused) {
186
+ loop = setInterval(() => {
187
+ }, options.delay ?? defaultDelay);
188
+ state.isPaused = false;
189
+ }
190
+ },
191
+ dispose: () => {
192
+ if (state.isActive) {
193
+ controls.stop();
194
+ }
195
+ state.isActive = false;
196
+ state.isPaused = false;
197
+ },
198
+ get isCancelled() {
199
+ return state.isCancelled;
200
+ }
201
+ };
202
+ return controls;
203
+ }
204
+ useSpinner.promise = async (operation, options) => {
205
+ const spinner = useSpinner(options).start();
206
+ try {
207
+ const result = await operation(spinner);
208
+ spinner.succeed();
209
+ return result;
210
+ } catch (error) {
211
+ spinner.fail();
212
+ throw error;
213
+ } finally {
214
+ spinner.dispose();
215
+ }
216
+ };
217
+ useSpinner.nested = (parentOptions) => {
218
+ const parentSpinner = useSpinner({
219
+ ...parentOptions,
220
+ silent: true
221
+ // Parent is silent, children will show progress
222
+ });
223
+ return {
224
+ start: () => {
225
+ parentSpinner.start();
226
+ return {
227
+ child: (childOptions) => useSpinner(childOptions),
228
+ finish: (success, text) => {
229
+ if (success) {
230
+ parentSpinner.succeed(text);
231
+ } else {
232
+ parentSpinner.fail(text);
233
+ }
234
+ },
235
+ dispose: () => parentSpinner.dispose()
236
+ };
237
+ }
238
+ };
239
+ };
240
+ useSpinner.withTiming = async (operation, options) => {
241
+ const spinner = useSpinner(options).start();
242
+ const startTime = Date.now();
243
+ try {
244
+ const result = await operation(spinner);
245
+ const duration = Date.now() - startTime;
246
+ spinner.succeed(`${options.successText || options.text} (${duration}ms)`);
247
+ return { result, duration };
248
+ } catch (error) {
249
+ const duration = Date.now() - startTime;
250
+ spinner.fail(`${options.failText || options.text} (failed after ${duration}ms)`);
251
+ throw error;
252
+ } finally {
253
+ spinner.dispose();
254
+ }
255
+ };
@@ -0,0 +1,2 @@
1
+ import type { ProgressBar, ProgressBarOptions } from "../../types";
2
+ export declare function taskProgressPrompt(options: ProgressBarOptions): Promise<ProgressBar>;
@@ -0,0 +1,57 @@
1
+ import { re } from "@reliverse/relico";
2
+ import { cursor, erase } from "sisteransi";
3
+ export async function taskProgressPrompt(options) {
4
+ if (options.total <= 0) {
5
+ throw new Error("Total must be a positive number");
6
+ }
7
+ const state = {
8
+ total: options.total,
9
+ current: 0,
10
+ width: options.width ?? 40,
11
+ completeChar: options.completeChar ?? "\u2588",
12
+ incompleteChar: options.incompleteChar ?? "\u2591",
13
+ startTime: Date.now(),
14
+ format: options.format ?? "Progress: [:bar] :percent% | Elapsed: :elapsed s",
15
+ colorize: options.colorize ?? false
16
+ };
17
+ const getElapsedTime = () => {
18
+ return ((Date.now() - state.startTime) / 1e3).toFixed(2);
19
+ };
20
+ const getPercentage = () => {
21
+ return (state.current / state.total * 100).toFixed(2);
22
+ };
23
+ const getBar = () => {
24
+ const percent = state.current / state.total;
25
+ const filledLength = Math.round(state.width * percent);
26
+ const emptyLength = state.width - filledLength;
27
+ const filled = state.completeChar.repeat(filledLength);
28
+ const empty = state.incompleteChar.repeat(emptyLength);
29
+ return state.colorize ? re.green(filled) + re.red(empty) : filled + empty;
30
+ };
31
+ const render = async () => {
32
+ const bar = getBar();
33
+ const percentage = getPercentage();
34
+ const elapsed = getElapsedTime();
35
+ const output = state.format.replace(":bar", bar).replace(":percent", percentage).replace(":elapsed", elapsed);
36
+ process.stdout.write(cursor.move(-999, 0) + erase.line);
37
+ process.stdout.write(`${re.green("\u25C6")} ${output}`);
38
+ if (state.current >= state.total) {
39
+ process.stdout.write("\n");
40
+ }
41
+ };
42
+ const update = async (value) => {
43
+ const newValue = Math.min(value, state.total);
44
+ if (newValue !== state.current) {
45
+ state.current = newValue;
46
+ await render();
47
+ }
48
+ };
49
+ const increment = async (amount = 1) => {
50
+ await update(state.current + amount);
51
+ };
52
+ return {
53
+ update,
54
+ increment,
55
+ render
56
+ };
57
+ }
@@ -0,0 +1,15 @@
1
+ import type { SpinnerName } from "cli-spinners";
2
+ type SimpleSpinnerType = "default" | "dottedCircle" | "boxSpinner";
3
+ type OraSpinnerType = Extract<SpinnerName, OraAllowedSpinners>;
4
+ type OraAllowedSpinners = "dots" | "bouncingBar" | "arc";
5
+ interface TaskOptions<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 taskSpinPrompt<T extends "simple" | "ora">(options: TaskOptions<T>): Promise<void>;
15
+ export {};
@@ -0,0 +1,106 @@
1
+ import process from "node:process";
2
+ import { re } from "@reliverse/relico";
3
+ import ora from "ora";
4
+ import { cursor, erase } from "sisteransi";
5
+ import { msg } from "../msg-fmt/messages.js";
6
+ export async function taskSpinPrompt(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: "cyan"
35
+ });
36
+ } catch (error) {
37
+ oraSpinner.stopAndPersist({
38
+ symbol: re.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 = re.magenta(frames[frameIndex] ?? "");
69
+ process.stdout.write(`${cursor.move(-999, 0)}${erase.line}${frame} ${re.cyan(message)}`);
70
+ frameIndex = (frameIndex + 1) % frames.length;
71
+ }, delay);
72
+ await action((newMessage) => {
73
+ message = newMessage;
74
+ });
75
+ clearInterval(interval);
76
+ interval = null;
77
+ process.stdout.write(`\r${erase.line}${re.green("\u2714")} ${successMessage}
78
+ `);
79
+ msg({
80
+ type: "M_INFO",
81
+ title: successMessage,
82
+ titleColor: "cyan"
83
+ });
84
+ } catch (error) {
85
+ if (interval) {
86
+ clearInterval(interval);
87
+ }
88
+ process.stdout.write(
89
+ `\r${erase.line}${re.red("\u2716")} ${error instanceof Error ? errorMessage : "An unknown error occurred."}
90
+ `
91
+ );
92
+ msg({
93
+ type: "M_ERROR",
94
+ title: error instanceof Error ? error.message : "An unknown error occurred.",
95
+ titleColor: "red"
96
+ });
97
+ process.exit(1);
98
+ } finally {
99
+ if (process.stdin.isTTY && typeof process.stdin.setRawMode === "function") {
100
+ process.stdin.setRawMode(false);
101
+ process.stdin.pause();
102
+ process.stdin.removeListener("data", handleInput);
103
+ }
104
+ }
105
+ }
106
+ }
@@ -0,0 +1,2 @@
1
+ import type { ColorName, TypographyName } from "../../types";
2
+ export declare function colorize(text: string, colorName?: ColorName, typography?: TypographyName): string;
@@ -0,0 +1,122 @@
1
+ import { re } from "@reliverse/relico";
2
+ import { relinka } from "@reliverse/relinka";
3
+ import gradient, { cristal, mind, passion, rainbow, vice } from "gradient-string";
4
+ function stripAnsi(text) {
5
+ return re.reset(text);
6
+ }
7
+ export function colorize(text, colorName, typography) {
8
+ if (!colorName) return text;
9
+ text = stripAnsi(text);
10
+ let result = text;
11
+ if (colorName.endsWith("Gradient")) {
12
+ switch (colorName) {
13
+ case "gradientGradient":
14
+ result = gradient(["red", "yellow", "green", "cyan", "blue", "magenta"])(result);
15
+ break;
16
+ case "rainbowGradient":
17
+ result = rainbow(result);
18
+ break;
19
+ case "cristalGradient":
20
+ result = cristal(result);
21
+ break;
22
+ case "mindGradient":
23
+ result = mind(result);
24
+ break;
25
+ case "passionGradient":
26
+ result = passion(result);
27
+ break;
28
+ case "viceGradient":
29
+ result = vice(result);
30
+ break;
31
+ case "retroGradient":
32
+ result = gradient(["#ff8a00", "#e52e71"])(result);
33
+ break;
34
+ default:
35
+ break;
36
+ }
37
+ return result;
38
+ }
39
+ switch (colorName) {
40
+ case "inverse":
41
+ result = re.inverse(` ${result} `);
42
+ break;
43
+ case "dim":
44
+ result = re.dim(result);
45
+ break;
46
+ case "black":
47
+ result = re.black(result);
48
+ break;
49
+ case "red":
50
+ result = re.red(result);
51
+ break;
52
+ case "redBright":
53
+ result = re.redBright(result);
54
+ break;
55
+ case "green":
56
+ result = re.green(result);
57
+ break;
58
+ case "greenBright":
59
+ result = re.greenBright(result);
60
+ break;
61
+ case "yellow":
62
+ result = re.yellow(result);
63
+ break;
64
+ case "yellowBright":
65
+ result = re.yellowBright(result);
66
+ break;
67
+ case "blue":
68
+ result = re.blue(result);
69
+ break;
70
+ case "blueBright":
71
+ result = re.blueBright(result);
72
+ break;
73
+ case "magenta":
74
+ result = re.magenta(result);
75
+ break;
76
+ case "magentaBright":
77
+ result = re.magentaBright(result);
78
+ break;
79
+ case "cyan":
80
+ result = re.cyan(result);
81
+ break;
82
+ case "cyanBright":
83
+ result = re.cyanBright(result);
84
+ break;
85
+ case "bgCyan":
86
+ result = re.bgCyan(` ${result} `);
87
+ break;
88
+ case "bgCyanBright":
89
+ result = re.bgCyanBright(` ${result} `);
90
+ break;
91
+ case "white":
92
+ result = re.white(result);
93
+ break;
94
+ case "gray":
95
+ result = re.gray(result);
96
+ break;
97
+ case "none":
98
+ break;
99
+ default:
100
+ relinka("warn", `Warning: Unknown color "${colorName}"`);
101
+ break;
102
+ }
103
+ if (typography) {
104
+ switch (typography) {
105
+ case "bold":
106
+ result = re.bold(result);
107
+ break;
108
+ case "strikethrough":
109
+ result = re.strikethrough(result);
110
+ break;
111
+ case "underline":
112
+ result = re.underline(result);
113
+ break;
114
+ case "italic":
115
+ result = re.italic(result);
116
+ break;
117
+ default:
118
+ break;
119
+ }
120
+ }
121
+ return result;
122
+ }
@@ -0,0 +1 @@
1
+ export declare const errorHandler: (error: Error, customMessage?: string) => never;
@@ -0,0 +1,17 @@
1
+ import { relinka } from "@reliverse/relinka";
2
+ export const errorHandler = (error, customMessage) => {
3
+ const separator = "\u2500".repeat(71);
4
+ relinka("error", `\u2502${separator}`);
5
+ relinka("error", "\u2502 AN ERROR OCCURRED:\n\u2502 ", error.message);
6
+ relinka("error", `\u2502${separator}`);
7
+ if (customMessage) {
8
+ relinka("error", `\u2502 ${customMessage}`);
9
+ } else {
10
+ relinka(
11
+ "error",
12
+ "\u2502 If this issue is related to @reliverse/rempts itself, please\n\u2502 report the details at https://github.com/reliverse/rempts/issues"
13
+ );
14
+ }
15
+ relinka("error", `\u2570${separator}`);
16
+ process.exit(1);
17
+ };
@@ -0,0 +1,8 @@
1
+ import type { PreventWrongTerminalSizeOptions } from "../../types";
2
+ export declare function preventUnsupportedTTY(): void;
3
+ /**
4
+ * Prevents EISDIR errors when trying to read Windows home directory as a file
5
+ * @param filePath The file path to check
6
+ */
7
+ export declare function preventWindowsHomeDirRoot(filePath: string): never | undefined;
8
+ export declare function preventWrongTerminalSize({ isDev, shouldExit, minWidth, minHeight, sizeErrorDescription, }: PreventWrongTerminalSizeOptions): Promise<void>;
@@ -0,0 +1,62 @@
1
+ import { homedir } from "node:os";
2
+ import { re } from "@reliverse/relico";
3
+ import { relinka } from "@reliverse/relinka";
4
+ import terminalSize from "terminal-size";
5
+ import { msg } from "../msg-fmt/messages.js";
6
+ import { getExactTerminalWidth, getTerminalWidth } from "../msg-fmt/terminal.js";
7
+ export function preventUnsupportedTTY() {
8
+ if (!process.stdout.isTTY) {
9
+ relinka(
10
+ "warn",
11
+ "\u2502 Your terminal does not support terminal's cursor manipulations.\n\u2502 It's recommended to use a terminal which supports TTY."
12
+ );
13
+ }
14
+ }
15
+ export function preventWindowsHomeDirRoot(filePath) {
16
+ if (process.platform !== "win32") {
17
+ return;
18
+ }
19
+ const home = homedir();
20
+ if (filePath === home || filePath === `${home}\\`) {
21
+ msg({
22
+ type: "M_ERROR",
23
+ title: re.redBright("Cannot operate in Windows home directory root"),
24
+ content: `Please use a command like ${re.cyan(`cd ${home}\\Desktop`)} to move to a safe working directory first.`,
25
+ contentColor: "redBright"
26
+ });
27
+ process.exit(1);
28
+ }
29
+ }
30
+ export async function preventWrongTerminalSize({
31
+ isDev = false,
32
+ shouldExit = true,
33
+ minWidth = 80,
34
+ minHeight = 12,
35
+ sizeErrorDescription = "Please increase the terminal size to run the application"
36
+ }) {
37
+ const size = terminalSize();
38
+ const exactTerminalWidth = getExactTerminalWidth();
39
+ const terminalWidth = getTerminalWidth();
40
+ const errors = [];
41
+ if (terminalWidth < minWidth) {
42
+ errors.push(
43
+ isDev ? `Oops! Terminal width is too small. Expected >${minWidth} | Current: ${terminalWidth} (Exact: ${exactTerminalWidth})` : `Oops! Terminal width is too small. Expected >${minWidth} | Current: ${terminalWidth}`
44
+ );
45
+ }
46
+ if (size.rows < minHeight) {
47
+ errors.push(
48
+ `Oops! Terminal height is too small. Expected >${minHeight} | Current: ${size.rows}`
49
+ );
50
+ }
51
+ if (errors.length > 0) {
52
+ msg({
53
+ type: "M_ERROR",
54
+ title: re.redBright(errors.join("\n\u2502\u2502 ")),
55
+ content: size.rows >= 7 && terminalWidth >= 70 ? sizeErrorDescription : "",
56
+ contentColor: "redBright"
57
+ });
58
+ if (shouldExit) {
59
+ process.exit(1);
60
+ }
61
+ }
62
+ }
@@ -0,0 +1,8 @@
1
+ import type { BorderColorName, ColorName, TypographyName, VariantName } from "../../types";
2
+ /**
3
+ * Ends the prompt by optionally displaying an end message and running the action if confirmed.
4
+ * Preserves the last prompt state unless there's an endTitle.
5
+ */
6
+ export declare function completePrompt(prompt: "input" | "confirm" | "select" | "multiselect" | "toggle", isCtrlC: boolean, _endTitle: string | undefined, _endTitleColor: ColorName | undefined, _titleTypography: TypographyName | undefined, _titleVariant: VariantName | undefined, _border?: boolean, borderColor?: BorderColorName, action?: () => Promise<void>, value?: boolean): Promise<boolean>;
7
+ export declare function renderEndLine(): void;
8
+ export declare function renderEndLineInput(): void;