@reliverse/rempts-core 1.6.1
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 +21 -0
- package/README.md +102 -0
- package/bin/core-impl/anykey/anykey-mod.d.ts +12 -0
- package/bin/core-impl/anykey/anykey-mod.js +125 -0
- package/bin/core-impl/date/date.d.ts +2 -0
- package/bin/core-impl/date/date.js +236 -0
- package/bin/core-impl/editor/editor-mod.d.ts +25 -0
- package/bin/core-impl/editor/editor-mod.js +896 -0
- package/bin/core-impl/figures/figures-mod.d.ts +233 -0
- package/bin/core-impl/figures/figures-mod.js +286 -0
- package/bin/core-impl/figures/figures.test.d.ts +1 -0
- package/bin/core-impl/figures/figures.test.js +474 -0
- package/bin/core-impl/input/confirm-prompt.d.ts +5 -0
- package/bin/core-impl/input/confirm-prompt.js +173 -0
- package/bin/core-impl/input/input-prompt.d.ts +16 -0
- package/bin/core-impl/input/input-prompt.js +370 -0
- package/bin/core-impl/launcher/_parser.d.ts +2 -0
- package/bin/core-impl/launcher/_parser.js +122 -0
- package/bin/core-impl/launcher/_utils.d.ts +8 -0
- package/bin/core-impl/launcher/_utils.js +29 -0
- package/bin/core-impl/launcher/args.d.ts +3 -0
- package/bin/core-impl/launcher/args.js +89 -0
- package/bin/core-impl/launcher/command.d.ts +8 -0
- package/bin/core-impl/launcher/command.js +68 -0
- package/bin/core-impl/launcher/launcher-mod.d.ts +8 -0
- package/bin/core-impl/launcher/launcher-mod.js +34 -0
- package/bin/core-impl/launcher/usage.d.ts +3 -0
- package/bin/core-impl/launcher/usage.js +104 -0
- package/bin/core-impl/msg-fmt/colors.d.ts +30 -0
- package/bin/core-impl/msg-fmt/colors.js +42 -0
- package/bin/core-impl/msg-fmt/logger.d.ts +17 -0
- package/bin/core-impl/msg-fmt/logger.js +106 -0
- package/bin/core-impl/msg-fmt/mapping.d.ts +3 -0
- package/bin/core-impl/msg-fmt/mapping.js +49 -0
- package/bin/core-impl/msg-fmt/messages.d.ts +35 -0
- package/bin/core-impl/msg-fmt/messages.js +314 -0
- package/bin/core-impl/msg-fmt/terminal.d.ts +15 -0
- package/bin/core-impl/msg-fmt/terminal.js +59 -0
- package/bin/core-impl/msg-fmt/variants.d.ts +11 -0
- package/bin/core-impl/msg-fmt/variants.js +52 -0
- package/bin/core-impl/next-steps/next-steps.d.ts +14 -0
- package/bin/core-impl/next-steps/next-steps.js +24 -0
- package/bin/core-impl/number/number-mod.d.ts +28 -0
- package/bin/core-impl/number/number-mod.js +197 -0
- package/bin/core-impl/results/results.d.ts +7 -0
- package/bin/core-impl/results/results.js +27 -0
- package/bin/core-impl/select/multiselect-prompt.d.ts +2 -0
- package/bin/core-impl/select/multiselect-prompt.js +341 -0
- package/bin/core-impl/select/nummultiselect-prompt.d.ts +6 -0
- package/bin/core-impl/select/nummultiselect-prompt.js +105 -0
- package/bin/core-impl/select/numselect-prompt.d.ts +7 -0
- package/bin/core-impl/select/numselect-prompt.js +115 -0
- package/bin/core-impl/select/select-prompt.d.ts +33 -0
- package/bin/core-impl/select/select-prompt.js +302 -0
- package/bin/core-impl/select/toggle-prompt.d.ts +5 -0
- package/bin/core-impl/select/toggle-prompt.js +208 -0
- package/bin/core-impl/st-end/end.d.ts +2 -0
- package/bin/core-impl/st-end/end.js +42 -0
- package/bin/core-impl/st-end/start.d.ts +17 -0
- package/bin/core-impl/st-end/start.js +66 -0
- package/bin/core-impl/task/progress.d.ts +2 -0
- package/bin/core-impl/task/progress.js +57 -0
- package/bin/core-impl/task/spinner.d.ts +15 -0
- package/bin/core-impl/task/spinner.js +110 -0
- package/bin/core-impl/utils/colorize.d.ts +2 -0
- package/bin/core-impl/utils/colorize.js +134 -0
- package/bin/core-impl/utils/errors.d.ts +1 -0
- package/bin/core-impl/utils/errors.js +15 -0
- package/bin/core-impl/utils/prevent.d.ts +10 -0
- package/bin/core-impl/utils/prevent.js +69 -0
- package/bin/core-impl/utils/prompt-end.d.ts +8 -0
- package/bin/core-impl/utils/prompt-end.js +33 -0
- package/bin/core-impl/utils/stream-text.d.ts +18 -0
- package/bin/core-impl/utils/stream-text.js +136 -0
- package/bin/core-impl/utils/system.d.ts +6 -0
- package/bin/core-impl/utils/system.js +7 -0
- package/bin/core-impl/utils/validate.d.ts +22 -0
- package/bin/core-impl/utils/validate.js +17 -0
- package/bin/core-impl/visual/animate/animate.d.ts +14 -0
- package/bin/core-impl/visual/animate/animate.js +64 -0
- package/bin/core-impl/visual/ascii-art/ascii-art.d.ts +6 -0
- package/bin/core-impl/visual/ascii-art/ascii-art.js +12 -0
- package/bin/core-types.d.ts +434 -0
- package/bin/core-types.js +0 -0
- package/bin/main.d.ts +41 -0
- package/bin/main.js +96 -0
- package/package.json +58 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 blefnk Nazar Kornienko
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# @reliverse/prompts
|
|
2
|
+
|
|
3
|
+
[💖 GitHub Sponsors](https://github.com/sponsors/blefnk) • [💬 Discord](https://discord.gg/3GawfWfAPe) • [📦 NPM](https://npmjs.com/package/@reliverse/prompts) • [📚 Docs](https://docs.reliverse.org/reliverse/prompts) • [✨ GitHub](https://github.com/reliverse/prompts)
|
|
4
|
+
|
|
5
|
+
**@reliverse/prompts** is your modern, type-safe toolkit for building delightful CLI experiences. It's fast, flexible, and built with developer joy in mind. Forget the clutter — this is how CLI should feel.
|
|
6
|
+
|
|
7
|
+
## ⚡ Why It Rocks
|
|
8
|
+
|
|
9
|
+
- ✨ **TypeScript-first** — fully typed prompts and helpers, with great DX
|
|
10
|
+
- 🔧 **Flexible Prompt Types** — input, password, select, multiselect, confirm, toggle, number, spinner, and more
|
|
11
|
+
- 🧠 **Smart validation** — works with Zod, TypeBox, or your own validators
|
|
12
|
+
- 🌈 **Accessible & Adaptive** — meets WCAG AA, handles terminal resizing & color contrast
|
|
13
|
+
- 🧯 **Crash-resistant** — gracefully exits on Ctrl+C or unexpected input
|
|
14
|
+
- 🎨 **Custom theming** — make it match your CLI style
|
|
15
|
+
- 🚀 **Zero boilerplate** — focus on the logic, not the wiring
|
|
16
|
+
|
|
17
|
+
## 🛠️ Install
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
bun add @reliverse/prompts
|
|
21
|
+
# or npm, pnpm, yarn
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Make sure you have [Bun](https://bun.sh), [Node.js](https://nodejs.org), and [Git](https://git-scm.com/downloads) installed.
|
|
25
|
+
|
|
26
|
+
## 🧪 Try It Out (Playground Mode)
|
|
27
|
+
|
|
28
|
+
Wanna test drive before integrating? Clone the repo and run:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
git clone https://github.com/reliverse/prompts.git
|
|
32
|
+
cd prompts
|
|
33
|
+
bun i
|
|
34
|
+
bun dev
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Then open `examples/launcher.ts` and explore different prompts.
|
|
38
|
+
|
|
39
|
+

|
|
40
|
+
|
|
41
|
+
## 🧩 Example Usage
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import {
|
|
45
|
+
startPrompt, // Initialize prompt session (optional)
|
|
46
|
+
inputPrompt, // Ask for user input
|
|
47
|
+
} from "@reliverse/prompts";
|
|
48
|
+
|
|
49
|
+
await startPrompt({
|
|
50
|
+
clearConsole: true,
|
|
51
|
+
titleColor: "inverse",
|
|
52
|
+
packageName: "@reliverse/cli",
|
|
53
|
+
packageVersion: "1.0.0",
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const username = await inputPrompt({
|
|
57
|
+
id: "username",
|
|
58
|
+
title: "Welcome!",
|
|
59
|
+
content: "What's your name?",
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
console.log(`Hey there, ${username}!`);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
> 🔎 You can also use `selectPrompt`, `multiselectPrompt`, `confirmPrompt`, `numberPrompt`, `spinnerPrompt`, and more.
|
|
66
|
+
|
|
67
|
+
## 🧠 Bonus Goodies
|
|
68
|
+
|
|
69
|
+
- ⚙️ **Built-in argument parsing** — parse CLI args without a separate lib
|
|
70
|
+
- 🧪 **Unit-test friendly** — prompts can be mocked/stubbed
|
|
71
|
+
- 📚 **Minimal API surface** — easy to learn, hard to outgrow
|
|
72
|
+
- 💅 **Custom styles** — tweak colors, formats, and transitions
|
|
73
|
+
|
|
74
|
+
## 🔍 Why not Inquirer or Clack?
|
|
75
|
+
|
|
76
|
+
While we love other tools, `@reliverse/prompts` was built for:
|
|
77
|
+
|
|
78
|
+
- Dev-first ergonomics
|
|
79
|
+
- Fully typed workflows
|
|
80
|
+
- Configurable theming
|
|
81
|
+
- Better crash handling & UX polish
|
|
82
|
+
|
|
83
|
+
[See feature comparison →](https://docs.reliverse.org/reliverse/prompts/#prompts-library-comparison)
|
|
84
|
+
|
|
85
|
+
## 💡 Contributing
|
|
86
|
+
|
|
87
|
+
Wanna improve prompts or add something cool? PRs welcome!
|
|
88
|
+
This project favors functional programming over OOP — no classes, just clean, composable logic.
|
|
89
|
+
|
|
90
|
+
Open a PR or discussion on [GitHub](https://github.com/reliverse/prompts).
|
|
91
|
+
|
|
92
|
+
## 🙏 Shoutout
|
|
93
|
+
|
|
94
|
+
This wouldn't exist without these gems:
|
|
95
|
+
|
|
96
|
+
- [sboudrias/inquirer.js](https://github.com/sboudrias/inquirer.js)
|
|
97
|
+
- [unjs/citty](https://github.com/unjs/citty)
|
|
98
|
+
- [lukeed/mri](https://github.com/lukeed/mri)
|
|
99
|
+
|
|
100
|
+
## 📄 License
|
|
101
|
+
|
|
102
|
+
💖 MIT © 2025 [blefnk Nazar Kornienko](https://github.com/blefnk)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ColorName } from "../../core-types.js";
|
|
2
|
+
type Options = {
|
|
3
|
+
ctrlC?: number | false | "reject";
|
|
4
|
+
preserveLog?: boolean;
|
|
5
|
+
hideMessage?: boolean;
|
|
6
|
+
shouldStream?: boolean;
|
|
7
|
+
streamDelay?: number;
|
|
8
|
+
color?: ColorName;
|
|
9
|
+
placeholderColor?: ColorName;
|
|
10
|
+
};
|
|
11
|
+
export declare function anykeyPrompt(message?: string, options?: Options): Promise<void>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import logUpdate from "log-update";
|
|
2
|
+
import { cursor } from "sisteransi";
|
|
3
|
+
import { fmt } from "../msg-fmt/messages.js";
|
|
4
|
+
import { endPrompt } from "../st-end/end.js";
|
|
5
|
+
import { streamText } from "../utils/stream-text.js";
|
|
6
|
+
const DEFAULT_MESSAGE = "Press any key to continue...";
|
|
7
|
+
const CTRL_C_CODE = 3;
|
|
8
|
+
const terminal = {
|
|
9
|
+
/**
|
|
10
|
+
* Move cursor to start of line
|
|
11
|
+
*/
|
|
12
|
+
moveToStart: () => process.stdout.write("\r"),
|
|
13
|
+
/**
|
|
14
|
+
* Clear current line and move cursor up
|
|
15
|
+
*/
|
|
16
|
+
clearLineAndMoveUp: () => process.stdout.write("\x1B[1A\x1B[2K"),
|
|
17
|
+
/**
|
|
18
|
+
* Clear multiple lines above current position
|
|
19
|
+
*/
|
|
20
|
+
clearLines: (count) => {
|
|
21
|
+
terminal.moveToStart();
|
|
22
|
+
process.stdout.write("\x1B[2K");
|
|
23
|
+
for (let i = 0; i < count; i++) {
|
|
24
|
+
terminal.clearLineAndMoveUp();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
export async function anykeyPrompt(message = DEFAULT_MESSAGE, options = {}) {
|
|
29
|
+
const {
|
|
30
|
+
ctrlC = 1,
|
|
31
|
+
preserveLog = false,
|
|
32
|
+
hideMessage = false,
|
|
33
|
+
shouldStream = false,
|
|
34
|
+
streamDelay = 20,
|
|
35
|
+
color = "dim",
|
|
36
|
+
placeholderColor = "gray"
|
|
37
|
+
} = options;
|
|
38
|
+
if (message) {
|
|
39
|
+
if (!shouldStream) {
|
|
40
|
+
const { text } = fmt({
|
|
41
|
+
hintPlaceholderColor: placeholderColor,
|
|
42
|
+
type: "M_GENERAL",
|
|
43
|
+
title: message,
|
|
44
|
+
titleColor: color,
|
|
45
|
+
dontRemoveBar: true
|
|
46
|
+
});
|
|
47
|
+
message = text;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (message && !hideMessage) {
|
|
51
|
+
if (shouldStream) {
|
|
52
|
+
await streamText({
|
|
53
|
+
text: `\u25C6 ${message}`,
|
|
54
|
+
delay: streamDelay,
|
|
55
|
+
newline: false,
|
|
56
|
+
clearLine: true,
|
|
57
|
+
color
|
|
58
|
+
});
|
|
59
|
+
const lineCount = message.split("\n").length;
|
|
60
|
+
terminal.clearLines(lineCount);
|
|
61
|
+
const { text } = fmt({
|
|
62
|
+
hintPlaceholderColor: placeholderColor,
|
|
63
|
+
type: "M_GENERAL",
|
|
64
|
+
title: message,
|
|
65
|
+
titleColor: color,
|
|
66
|
+
dontRemoveBar: true
|
|
67
|
+
});
|
|
68
|
+
terminal.moveToStart();
|
|
69
|
+
logUpdate(text);
|
|
70
|
+
} else {
|
|
71
|
+
logUpdate(message);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return new Promise((resolve, reject) => {
|
|
75
|
+
const cleanup = () => {
|
|
76
|
+
process.stdin.removeListener("data", handler);
|
|
77
|
+
if (process.stdin.isTTY && typeof process.stdin.setRawMode === "function") {
|
|
78
|
+
process.stdin.setRawMode(false);
|
|
79
|
+
}
|
|
80
|
+
process.stdin.pause();
|
|
81
|
+
process.stdout.write(cursor.show);
|
|
82
|
+
};
|
|
83
|
+
const handleCtrlC = () => {
|
|
84
|
+
cleanup();
|
|
85
|
+
void endPrompt({
|
|
86
|
+
title: "\u270B User pressed Ctrl+C, exiting...",
|
|
87
|
+
titleAnimation: "pulse",
|
|
88
|
+
titleColor: "redBright",
|
|
89
|
+
titleTypography: "bold",
|
|
90
|
+
endTitleColor: "redBright",
|
|
91
|
+
titleAnimationDelay: 400
|
|
92
|
+
}).then(() => {
|
|
93
|
+
if (ctrlC === "reject") {
|
|
94
|
+
reject(new Error("User pressed CTRL+C"));
|
|
95
|
+
} else if (ctrlC === false) {
|
|
96
|
+
resolve();
|
|
97
|
+
} else if (typeof ctrlC === "number") {
|
|
98
|
+
process.exit(0);
|
|
99
|
+
} else {
|
|
100
|
+
throw new TypeError("Invalid ctrlC option");
|
|
101
|
+
}
|
|
102
|
+
}).catch(reject);
|
|
103
|
+
};
|
|
104
|
+
const handler = (buffer) => {
|
|
105
|
+
cleanup();
|
|
106
|
+
if (message && !preserveLog) {
|
|
107
|
+
logUpdate.clear();
|
|
108
|
+
} else {
|
|
109
|
+
logUpdate.done();
|
|
110
|
+
process.stdout.write("\n");
|
|
111
|
+
}
|
|
112
|
+
const [firstByte] = buffer;
|
|
113
|
+
if (firstByte === CTRL_C_CODE) {
|
|
114
|
+
handleCtrlC();
|
|
115
|
+
} else {
|
|
116
|
+
resolve();
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
process.stdin.resume();
|
|
120
|
+
if (process.stdin.isTTY && typeof process.stdin.setRawMode === "function") {
|
|
121
|
+
process.stdin.setRawMode(true);
|
|
122
|
+
}
|
|
123
|
+
process.stdin.once("data", handler);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { re } from "@reliverse/relico";
|
|
2
|
+
import { stdin as input, stdout as output } from "node:process";
|
|
3
|
+
import readline from "node:readline/promises";
|
|
4
|
+
import {
|
|
5
|
+
buildRegExp,
|
|
6
|
+
digit,
|
|
7
|
+
endOfString,
|
|
8
|
+
repeat,
|
|
9
|
+
startOfString
|
|
10
|
+
} from "ts-regex-builder";
|
|
11
|
+
import { fmt, msg, symbols } from "../msg-fmt/messages.js";
|
|
12
|
+
import {
|
|
13
|
+
countLines,
|
|
14
|
+
deleteLastLine,
|
|
15
|
+
deleteLastLines
|
|
16
|
+
} from "../msg-fmt/terminal.js";
|
|
17
|
+
const twoDigits = repeat(digit, 2);
|
|
18
|
+
const fourDigits = repeat(digit, 4);
|
|
19
|
+
const separatorDot = ".";
|
|
20
|
+
const separatorSlash = "/";
|
|
21
|
+
const regexDDMMYYYY = buildRegExp([
|
|
22
|
+
startOfString,
|
|
23
|
+
twoDigits,
|
|
24
|
+
// DD
|
|
25
|
+
separatorDot,
|
|
26
|
+
twoDigits,
|
|
27
|
+
// MM
|
|
28
|
+
separatorDot,
|
|
29
|
+
fourDigits,
|
|
30
|
+
// YYYY
|
|
31
|
+
endOfString
|
|
32
|
+
]);
|
|
33
|
+
const regexMMDDYYYY = buildRegExp([
|
|
34
|
+
startOfString,
|
|
35
|
+
twoDigits,
|
|
36
|
+
// MM
|
|
37
|
+
separatorSlash,
|
|
38
|
+
twoDigits,
|
|
39
|
+
// DD
|
|
40
|
+
separatorSlash,
|
|
41
|
+
fourDigits,
|
|
42
|
+
// YYYY
|
|
43
|
+
endOfString
|
|
44
|
+
]);
|
|
45
|
+
const regexYYYYMMDD = buildRegExp([
|
|
46
|
+
startOfString,
|
|
47
|
+
fourDigits,
|
|
48
|
+
// YYYY
|
|
49
|
+
separatorDot,
|
|
50
|
+
twoDigits,
|
|
51
|
+
// MM
|
|
52
|
+
separatorDot,
|
|
53
|
+
twoDigits,
|
|
54
|
+
// DD
|
|
55
|
+
endOfString
|
|
56
|
+
]);
|
|
57
|
+
export async function datePrompt(opts) {
|
|
58
|
+
const {
|
|
59
|
+
title = "",
|
|
60
|
+
dateFormat,
|
|
61
|
+
dateKind,
|
|
62
|
+
hint,
|
|
63
|
+
hintPlaceholderColor = "blue",
|
|
64
|
+
validate,
|
|
65
|
+
defaultValue = "",
|
|
66
|
+
titleColor = "cyan",
|
|
67
|
+
titleTypography = "none",
|
|
68
|
+
titleVariant,
|
|
69
|
+
content,
|
|
70
|
+
contentColor = "dim",
|
|
71
|
+
contentTypography = "italic",
|
|
72
|
+
contentVariant,
|
|
73
|
+
borderColor = "dim",
|
|
74
|
+
variantOptions,
|
|
75
|
+
endTitle = "",
|
|
76
|
+
endTitleColor = "dim",
|
|
77
|
+
border = true
|
|
78
|
+
} = opts;
|
|
79
|
+
const rl = readline.createInterface({ input, output });
|
|
80
|
+
rl.on("SIGINT", () => {
|
|
81
|
+
rl.close();
|
|
82
|
+
if (endTitle !== "") {
|
|
83
|
+
msg({
|
|
84
|
+
type: "M_END",
|
|
85
|
+
title: endTitle,
|
|
86
|
+
titleColor: endTitleColor,
|
|
87
|
+
titleTypography,
|
|
88
|
+
border,
|
|
89
|
+
borderColor
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
process.exit(0);
|
|
93
|
+
});
|
|
94
|
+
let linesToDelete = 0;
|
|
95
|
+
let errorMessage = "";
|
|
96
|
+
try {
|
|
97
|
+
while (true) {
|
|
98
|
+
if (linesToDelete > 0) {
|
|
99
|
+
deleteLastLines(linesToDelete);
|
|
100
|
+
linesToDelete = 0;
|
|
101
|
+
}
|
|
102
|
+
const { text: questionText } = fmt({
|
|
103
|
+
type: errorMessage !== "" ? "M_ERROR_NULL" : "M_GENERAL_NULL",
|
|
104
|
+
title: `${title} [${dateFormat}]`,
|
|
105
|
+
titleColor,
|
|
106
|
+
titleTypography,
|
|
107
|
+
titleVariant,
|
|
108
|
+
content,
|
|
109
|
+
contentColor,
|
|
110
|
+
contentTypography,
|
|
111
|
+
contentVariant,
|
|
112
|
+
borderColor,
|
|
113
|
+
hint: `${hint ? `${hint} ` : ""}${defaultValue ? `Default: ${defaultValue}` : ""}`,
|
|
114
|
+
hintPlaceholderColor,
|
|
115
|
+
variantOptions,
|
|
116
|
+
errorMessage
|
|
117
|
+
});
|
|
118
|
+
const questionLines = countLines(questionText);
|
|
119
|
+
linesToDelete = questionLines + 1;
|
|
120
|
+
msg({
|
|
121
|
+
type: errorMessage !== "" ? "M_ERROR" : "M_GENERAL",
|
|
122
|
+
title: questionText
|
|
123
|
+
});
|
|
124
|
+
if (errorMessage !== "") {
|
|
125
|
+
deleteLastLine();
|
|
126
|
+
deleteLastLine();
|
|
127
|
+
}
|
|
128
|
+
const answerInput = await rl.question(`${re.dim(symbols.middle)} `);
|
|
129
|
+
if (answerInput === null) {
|
|
130
|
+
rl.close();
|
|
131
|
+
if (endTitle !== "") {
|
|
132
|
+
msg({
|
|
133
|
+
type: "M_END",
|
|
134
|
+
title: endTitle,
|
|
135
|
+
titleColor: endTitleColor,
|
|
136
|
+
titleTypography,
|
|
137
|
+
border,
|
|
138
|
+
borderColor
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
process.exit(0);
|
|
142
|
+
}
|
|
143
|
+
const answer = answerInput.trim() || defaultValue;
|
|
144
|
+
if (errorMessage !== "") {
|
|
145
|
+
deleteLastLine();
|
|
146
|
+
}
|
|
147
|
+
deleteLastLine();
|
|
148
|
+
msg({
|
|
149
|
+
type: "M_MIDDLE",
|
|
150
|
+
title: ` ${answer}`,
|
|
151
|
+
titleColor: "none"
|
|
152
|
+
});
|
|
153
|
+
if (!(regexDDMMYYYY.test(answer) || regexMMDDYYYY.test(answer) || regexYYYYMMDD.test(answer))) {
|
|
154
|
+
if (errorMessage !== "") {
|
|
155
|
+
deleteLastLine();
|
|
156
|
+
deleteLastLine();
|
|
157
|
+
}
|
|
158
|
+
errorMessage = `Please enter a valid date in ${dateFormat} format.`;
|
|
159
|
+
msg({ type: "M_ERROR", title: errorMessage });
|
|
160
|
+
linesToDelete = countLines(errorMessage) + 1;
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
let matchedFormat = null;
|
|
164
|
+
if (regexDDMMYYYY.test(answer)) {
|
|
165
|
+
matchedFormat = "DD.MM.YYYY";
|
|
166
|
+
} else if (regexMMDDYYYY.test(answer)) {
|
|
167
|
+
matchedFormat = "MM/DD/YYYY";
|
|
168
|
+
} else if (regexYYYYMMDD.test(answer)) {
|
|
169
|
+
matchedFormat = "YYYY.MM.DD";
|
|
170
|
+
}
|
|
171
|
+
if (dateKind === "birthday" && matchedFormat) {
|
|
172
|
+
const parts = answer.split(/[./-]/);
|
|
173
|
+
let date;
|
|
174
|
+
if (matchedFormat === "DD.MM.YYYY") {
|
|
175
|
+
date = new Date(
|
|
176
|
+
Number(parts[2]),
|
|
177
|
+
Number(parts[1]) - 1,
|
|
178
|
+
Number(parts[0])
|
|
179
|
+
);
|
|
180
|
+
} else if (matchedFormat === "MM/DD/YYYY") {
|
|
181
|
+
date = new Date(
|
|
182
|
+
Number(parts[2]),
|
|
183
|
+
Number(parts[0]) - 1,
|
|
184
|
+
Number(parts[1])
|
|
185
|
+
);
|
|
186
|
+
} else if (matchedFormat === "YYYY.MM.DD") {
|
|
187
|
+
date = new Date(
|
|
188
|
+
Number(parts[0]),
|
|
189
|
+
Number(parts[1]) - 1,
|
|
190
|
+
Number(parts[2])
|
|
191
|
+
);
|
|
192
|
+
} else {
|
|
193
|
+
date = new Date(answer);
|
|
194
|
+
}
|
|
195
|
+
if (Number.isNaN(date.getTime()) || date.getFullYear() < 1900 || date > /* @__PURE__ */ new Date()) {
|
|
196
|
+
errorMessage = "Please enter a valid birthday date (e.g., 14.09.1999).";
|
|
197
|
+
msg({ type: "M_ERROR", title: errorMessage });
|
|
198
|
+
linesToDelete = countLines(errorMessage) + 1;
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
let isValid = true;
|
|
203
|
+
let gotError = false;
|
|
204
|
+
if (errorMessage !== "") {
|
|
205
|
+
gotError = true;
|
|
206
|
+
}
|
|
207
|
+
errorMessage = "";
|
|
208
|
+
if (validate && isValid) {
|
|
209
|
+
const validation = await validate(answer);
|
|
210
|
+
if (validation !== true) {
|
|
211
|
+
isValid = false;
|
|
212
|
+
errorMessage = typeof validation === "string" ? validation : "Invalid input.";
|
|
213
|
+
msg({ type: "M_ERROR", title: errorMessage });
|
|
214
|
+
gotError = true;
|
|
215
|
+
linesToDelete = countLines(errorMessage) + 1;
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (isValid) {
|
|
220
|
+
if (gotError) {
|
|
221
|
+
deleteLastLine();
|
|
222
|
+
deleteLastLine();
|
|
223
|
+
msg({ type: "M_MIDDLE", title: ` ${answer}` });
|
|
224
|
+
}
|
|
225
|
+
msg({
|
|
226
|
+
type: "M_BAR",
|
|
227
|
+
borderColor
|
|
228
|
+
});
|
|
229
|
+
rl.close();
|
|
230
|
+
return answer;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
} finally {
|
|
234
|
+
rl.close();
|
|
235
|
+
}
|
|
236
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { EditorExitResult } from "../../core-types.js";
|
|
2
|
+
type EditorConfig = {
|
|
3
|
+
syntaxHighlighting?: boolean;
|
|
4
|
+
theme?: "auto" | "light" | "dark";
|
|
5
|
+
defaultAllowSaveAs?: boolean;
|
|
6
|
+
defaultAllowOpen?: boolean;
|
|
7
|
+
defaultAutoCloseOnSave?: boolean;
|
|
8
|
+
defaultReturnContentOnSave?: boolean;
|
|
9
|
+
[key: string]: any;
|
|
10
|
+
};
|
|
11
|
+
type EditorOptions = {
|
|
12
|
+
filename?: string | null;
|
|
13
|
+
initialContent?: string | null;
|
|
14
|
+
onSave?: (content: string, filename: string | null) => Promise<string | boolean | undefined> | string | boolean | undefined;
|
|
15
|
+
onExit?: (content: string | null, saved: boolean, filename: string | null) => Promise<void> | void;
|
|
16
|
+
configOverrides?: Partial<EditorConfig>;
|
|
17
|
+
allowSaveAs?: boolean;
|
|
18
|
+
allowOpen?: boolean;
|
|
19
|
+
autoCloseOnSave?: boolean;
|
|
20
|
+
returnContentOnSave?: boolean;
|
|
21
|
+
mode?: string;
|
|
22
|
+
cwd?: string;
|
|
23
|
+
};
|
|
24
|
+
export declare function startEditor(options?: EditorOptions): Promise<EditorExitResult>;
|
|
25
|
+
export {};
|