@reliverse/rempts 1.7.27 → 1.7.29
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/README.md +84 -8
- package/bin/components/aliases/aliases-mod.d.ts +11 -0
- package/bin/components/aliases/aliases-mod.js +16 -0
- package/bin/components/{visual/animate → animate}/animate.d.ts +1 -1
- package/bin/components/{visual/animate → animate}/animate.js +2 -2
- package/bin/components/anykey/anykey-mod.d.ts +2 -2
- package/bin/components/anykey/anykey-mod.js +2 -2
- package/bin/components/cancel/cancel.d.ts +45 -0
- package/bin/components/cancel/cancel.js +72 -0
- package/bin/components/editor/editor-mod.d.ts +4 -4
- package/bin/components/{st-end/start.d.ts → intro/intro-start.d.ts} +4 -1
- package/bin/components/{st-end/start.js → intro/intro-start.js} +33 -19
- package/bin/components/launcher/launcher-types.d.ts +14 -14
- package/bin/components/log/log.d.ts +2 -0
- package/bin/components/log/log.js +2 -0
- package/bin/components/next-steps/next-steps.d.ts +2 -2
- package/bin/components/number/number-mod.d.ts +2 -2
- package/bin/components/outro/outro-end.d.ts +8 -0
- package/bin/components/outro/outro-end.js +55 -0
- package/bin/components/results/results.d.ts +2 -2
- package/bin/components/select/select-prompt.d.ts +6 -5
- package/bin/components/select/select-prompt.js +4 -2
- package/bin/components/spinner/spinner-mod.d.ts +106 -0
- package/bin/components/spinner/spinner-mod.js +263 -0
- package/bin/components/task/progress.d.ts +1 -1
- package/bin/components/task/progress.js +1 -1
- package/bin/components/task/{spinner.d.ts → task-spin.d.ts} +3 -3
- package/bin/components/task/{spinner.js → task-spin.js} +1 -1
- package/bin/mod.d.ts +11 -8
- package/bin/mod.js +31 -8
- package/bin/types.d.ts +36 -36
- package/bin/utils/validate.d.ts +2 -2
- package/package.json +2 -2
- package/bin/components/st-end/end.d.ts +0 -2
- package/bin/components/st-end/end.js +0 -42
- package/bin/hooks/spinner/spinner-mod.d.ts +0 -64
- package/bin/hooks/spinner/spinner-mod.js +0 -74
- /package/bin/components/{visual/ascii-art → ascii-art}/ascii-art.d.ts +0 -0
- /package/bin/components/{visual/ascii-art → ascii-art}/ascii-art.js +0 -0
- /package/bin/components/{input → confirm}/confirm-prompt.d.ts +0 -0
- /package/bin/components/{input → confirm}/confirm-prompt.js +0 -0
package/README.md
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
|
-
- 😘 drop-in
|
|
9
|
+
- 😘 drop-in to libraries like `unjs/citty` and `@clack/prompts`
|
|
10
|
+
- 📝 includes comprehensive set of built-in cli prompts
|
|
10
11
|
- 📂 file-based commands (app-router style by default)
|
|
11
12
|
- 🫂 rempts keeps you from fighting with your CLI tool
|
|
12
13
|
- 🏎️ prompt engine that *feels* modern — and actually is
|
|
@@ -60,7 +61,7 @@ import {
|
|
|
60
61
|
// ...prompts
|
|
61
62
|
defineCommand, runMain, defineArgs,
|
|
62
63
|
inputPrompt, selectPrompt, multiselectPrompt, numberPrompt,
|
|
63
|
-
confirmPrompt, togglePrompt,
|
|
64
|
+
confirmPrompt, togglePrompt, taskSpinPrompt, taskProgressPrompt,
|
|
64
65
|
startPrompt, endPrompt, resultPrompt, nextStepsPrompt,
|
|
65
66
|
// ...hooks
|
|
66
67
|
useSpinner,
|
|
@@ -79,25 +80,32 @@ import {
|
|
|
79
80
|
|
|
80
81
|
| Prompt | Description |
|
|
81
82
|
|---------------------------|-----------------------------------------------------------|
|
|
83
|
+
| `useSpinner` | Start/stop spinner |
|
|
82
84
|
| `inputPrompt` | Single-line input (with mask support, e.g. for passwords) |
|
|
83
85
|
| `selectPrompt` | Single-choice radio menu |
|
|
84
86
|
| `multiselectPrompt` | Multi-choice checkbox menu |
|
|
85
87
|
| `numberPrompt` | Type-safe number input |
|
|
86
88
|
| `confirmPrompt` | Yes/No toggle |
|
|
87
89
|
| `togglePrompt` | Custom on/off toggles |
|
|
88
|
-
| `
|
|
90
|
+
| `taskProgressPrompt` | Progress bar for async tasks |
|
|
89
91
|
| `resultPrompt` | Show results in a styled box |
|
|
90
92
|
| `nextStepsPrompt` | Show next steps in a styled list |
|
|
91
93
|
| `startPrompt`/`endPrompt` | Makes CLI start/end flows look nice |
|
|
92
|
-
| `
|
|
94
|
+
| `taskSpinPrompt` | Async loader with spinner (possibly will be deprecated) |
|
|
93
95
|
| `datePrompt` | Date input with format validation |
|
|
94
96
|
| `anykeyPrompt` | Wait for any keypress |
|
|
95
97
|
|
|
96
|
-
###
|
|
98
|
+
### Aliases
|
|
97
99
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
|
100
|
+
To help you migrate from the different CLI frameworks, `@reliverse/rempts` has some aliases for the most popular prompts.
|
|
101
|
+
|
|
102
|
+
| Prompt | Aliases |
|
|
103
|
+
|-----------------------|-----------------|
|
|
104
|
+
| `useSpinner` | `spinner` |
|
|
105
|
+
| `selectPrompt` | `select` |
|
|
106
|
+
| `multiselectPrompt` | `multiselect` |
|
|
107
|
+
| `inputPrompt` | `text`, `input` |
|
|
108
|
+
| `@reliverse/relinka` | `log` |
|
|
101
109
|
|
|
102
110
|
### Notices
|
|
103
111
|
|
|
@@ -124,6 +132,23 @@ async function main() {
|
|
|
124
132
|
defaultValue: "my-cool-project",
|
|
125
133
|
});
|
|
126
134
|
|
|
135
|
+
const spinner = useSpinner({
|
|
136
|
+
text: "Loading...",
|
|
137
|
+
indicator: "timer", // or "dots"
|
|
138
|
+
frames: ["◒", "◐", "◓", "◑"], // custom frames
|
|
139
|
+
delay: 80, // custom delay
|
|
140
|
+
onCancel: () => {
|
|
141
|
+
console.log("Operation cancelled");
|
|
142
|
+
},
|
|
143
|
+
cancelMessage: "Operation cancelled by user",
|
|
144
|
+
errorMessage: "Operation failed",
|
|
145
|
+
signal: abortController.signal,
|
|
146
|
+
}).start();
|
|
147
|
+
|
|
148
|
+
// The spinner will show:
|
|
149
|
+
// ◒ Loading... [5s]
|
|
150
|
+
// With animated frames and timer
|
|
151
|
+
|
|
127
152
|
const framework = await selectPrompt({
|
|
128
153
|
title: "Pick your framework",
|
|
129
154
|
options: [
|
|
@@ -140,6 +165,57 @@ async function main() {
|
|
|
140
165
|
await main();
|
|
141
166
|
```
|
|
142
167
|
|
|
168
|
+
**Available spinner options:**
|
|
169
|
+
|
|
170
|
+
| Option | Description |
|
|
171
|
+
|--------|-------------|
|
|
172
|
+
| `cancelMessage` | The message to display when the spinner is cancelled |
|
|
173
|
+
| `color` | The color of the spinner |
|
|
174
|
+
| `delay` | The delay between frames |
|
|
175
|
+
| `errorMessage` | The message to display when the spinner fails |
|
|
176
|
+
| `failText` | The text to display when the spinner fails |
|
|
177
|
+
| `frames` | The frames to use for the spinner |
|
|
178
|
+
| `hideCursor` | Whether to hide the cursor |
|
|
179
|
+
| `indicator` | The indicator to use for the spinner |
|
|
180
|
+
| `onCancel` | The function to call when the spinner is cancelled |
|
|
181
|
+
| `prefixText` | The text to display before the spinner |
|
|
182
|
+
| `signal` | The signal to use for the spinner |
|
|
183
|
+
| `silent` | Whether to hide the spinner |
|
|
184
|
+
| `spinner` | The spinner to use for the spinner |
|
|
185
|
+
| `successText` | The text to display when the spinner succeeds |
|
|
186
|
+
| `text` | The text to display next to the spinner |
|
|
187
|
+
|
|
188
|
+
**Available indicator options:**
|
|
189
|
+
|
|
190
|
+
| Option | Description |
|
|
191
|
+
|--------|-------------|
|
|
192
|
+
| `timer` | The timer indicator |
|
|
193
|
+
| `dots` | The dots indicator |
|
|
194
|
+
|
|
195
|
+
**Available signal options:**
|
|
196
|
+
|
|
197
|
+
| Option | Description |
|
|
198
|
+
|--------|-------------|
|
|
199
|
+
| `abortController.signal` | The signal to use for the spinner |
|
|
200
|
+
|
|
201
|
+
**Available frames options:**
|
|
202
|
+
|
|
203
|
+
| Option | Description |
|
|
204
|
+
|--------|-------------|
|
|
205
|
+
| `["◒", "◐", "◓", "◑"]` | The frames to use for the spinner |
|
|
206
|
+
|
|
207
|
+
**Available delay options:**
|
|
208
|
+
|
|
209
|
+
| Option | Description |
|
|
210
|
+
|--------|-------------|
|
|
211
|
+
| `80` | The delay between frames |
|
|
212
|
+
|
|
213
|
+
**Available onCancel options:**
|
|
214
|
+
|
|
215
|
+
| Option | Description |
|
|
216
|
+
|--------|-------------|
|
|
217
|
+
| `() => { console.log("Operation cancelled"); }` | The function to call when the spinner is cancelled |
|
|
218
|
+
|
|
143
219
|
## Launcher
|
|
144
220
|
|
|
145
221
|
### Terminology
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { InputPromptOptions } from "../../types.js";
|
|
2
|
+
export declare const password: (options: Omit<InputPromptOptions, "mode">) => any;
|
|
3
|
+
export declare const multiselect: any;
|
|
4
|
+
export declare const select: any;
|
|
5
|
+
export declare const input: any;
|
|
6
|
+
export declare const text: any;
|
|
7
|
+
export declare const startPrompt: any;
|
|
8
|
+
export declare const intro: any;
|
|
9
|
+
export declare const endPrompt: any;
|
|
10
|
+
export declare const outro: any;
|
|
11
|
+
export declare const spinner: any;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { inputPrompt } from "../input/input-prompt.js";
|
|
2
|
+
import { introPrompt } from "../intro/intro-start.js";
|
|
3
|
+
import { outroPrompt } from "../outro/outro-end.js";
|
|
4
|
+
import { multiselectPrompt } from "../select/multiselect-prompt.js";
|
|
5
|
+
import { selectPrompt } from "../select/select-prompt.js";
|
|
6
|
+
import { useSpinner } from "../spinner/spinner-mod.js";
|
|
7
|
+
export const password = (options) => inputPrompt({ ...options, mode: "password" });
|
|
8
|
+
export const multiselect = multiselectPrompt;
|
|
9
|
+
export const select = selectPrompt;
|
|
10
|
+
export const input = inputPrompt;
|
|
11
|
+
export const text = inputPrompt;
|
|
12
|
+
export const startPrompt = introPrompt;
|
|
13
|
+
export const intro = introPrompt;
|
|
14
|
+
export const endPrompt = outroPrompt;
|
|
15
|
+
export const outro = outroPrompt;
|
|
16
|
+
export const spinner = useSpinner;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Animation, type AnimationName } from "@figliolia/chalk-animation";
|
|
2
|
-
import type { BorderColorName, ColorName, MsgType, TypographyName } from "
|
|
2
|
+
import type { BorderColorName, ColorName, MsgType, TypographyName } from "../../types.js";
|
|
3
3
|
export declare const animationMap: Record<AnimationName, (text: string) => Animation>;
|
|
4
4
|
export declare function animateText({ title, anim, delay, type, titleColor, titleTypography, border, borderColor, horizontalLineLength, }: {
|
|
5
5
|
title: string;
|
|
@@ -2,11 +2,11 @@ import {
|
|
|
2
2
|
ChalkAnimation
|
|
3
3
|
} from "@figliolia/chalk-animation";
|
|
4
4
|
import { relinka } from "@reliverse/relinka";
|
|
5
|
-
import { msg } from "
|
|
5
|
+
import { msg } from "../msg-fmt/messages.js";
|
|
6
6
|
import {
|
|
7
7
|
deleteLastLine,
|
|
8
8
|
getTerminalWidth
|
|
9
|
-
} from "
|
|
9
|
+
} from "../msg-fmt/terminal.js";
|
|
10
10
|
export const animationMap = {
|
|
11
11
|
rainbow: ChalkAnimation.rainbow,
|
|
12
12
|
pulse: ChalkAnimation.pulse,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ColorName } from "../../types.js";
|
|
2
|
-
|
|
2
|
+
interface Options {
|
|
3
3
|
ctrlC?: number | false | "reject";
|
|
4
4
|
preserveLog?: boolean;
|
|
5
5
|
hideMessage?: boolean;
|
|
@@ -7,6 +7,6 @@ type Options = {
|
|
|
7
7
|
streamDelay?: number;
|
|
8
8
|
color?: ColorName;
|
|
9
9
|
placeholderColor?: ColorName;
|
|
10
|
-
}
|
|
10
|
+
}
|
|
11
11
|
export declare function anykeyPrompt(message?: string, options?: Options): Promise<void>;
|
|
12
12
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import logUpdate from "log-update";
|
|
2
2
|
import { cursor } from "sisteransi";
|
|
3
3
|
import { fmt } from "../msg-fmt/messages.js";
|
|
4
|
-
import {
|
|
4
|
+
import { outroPrompt } from "../outro/outro-end.js";
|
|
5
5
|
import { streamText } from "../../utils/stream-text.js";
|
|
6
6
|
const DEFAULT_MESSAGE = "Press any key to continue...";
|
|
7
7
|
const CTRL_C_CODE = 3;
|
|
@@ -82,7 +82,7 @@ export async function anykeyPrompt(message = DEFAULT_MESSAGE, options = {}) {
|
|
|
82
82
|
};
|
|
83
83
|
const handleCtrlC = () => {
|
|
84
84
|
cleanup();
|
|
85
|
-
void
|
|
85
|
+
void outroPrompt({
|
|
86
86
|
title: "\u270B User pressed Ctrl+C, exiting...",
|
|
87
87
|
titleAnimation: "pulse",
|
|
88
88
|
titleColor: "redBright",
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Readable, Writable } from "node:stream";
|
|
2
|
+
/**
|
|
3
|
+
* Special value that indicates a cancelled operation
|
|
4
|
+
*/
|
|
5
|
+
export declare const CANCEL: unique symbol;
|
|
6
|
+
/**
|
|
7
|
+
* Type for the cancel value
|
|
8
|
+
*/
|
|
9
|
+
export type CancelValue = typeof CANCEL;
|
|
10
|
+
export declare const isWindows: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Sets raw mode on input stream
|
|
13
|
+
*/
|
|
14
|
+
export declare function setRawMode(input: Readable, value: boolean): void;
|
|
15
|
+
/**
|
|
16
|
+
* Gets the number of columns in the terminal
|
|
17
|
+
*/
|
|
18
|
+
export declare function getColumns(output: Writable): number;
|
|
19
|
+
interface BlockOptions {
|
|
20
|
+
input?: Readable;
|
|
21
|
+
output?: Writable;
|
|
22
|
+
overwrite?: boolean;
|
|
23
|
+
hideCursor?: boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Creates a block for handling input with proper cursor and cleanup
|
|
27
|
+
*/
|
|
28
|
+
export declare function block({ input, output, overwrite, hideCursor, }?: BlockOptions): () => void;
|
|
29
|
+
/**
|
|
30
|
+
* Checks if a value represents a cancelled operation
|
|
31
|
+
* @param value - The value to check
|
|
32
|
+
* @returns true if the value represents a cancelled operation
|
|
33
|
+
*/
|
|
34
|
+
export declare function isCancel(value: unknown): value is CancelValue;
|
|
35
|
+
/**
|
|
36
|
+
* Handles cancellation of an operation
|
|
37
|
+
* @param message - Optional message to display before exiting
|
|
38
|
+
*/
|
|
39
|
+
export declare function cancel(message?: string): never;
|
|
40
|
+
/**
|
|
41
|
+
* Creates a cancel value that can be returned from operations
|
|
42
|
+
* @returns The cancel value
|
|
43
|
+
*/
|
|
44
|
+
export declare function createCancel(): CancelValue;
|
|
45
|
+
export {};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { stdin, stdout } from "node:process";
|
|
2
|
+
import * as readline from "node:readline";
|
|
3
|
+
import { ReadStream, WriteStream } from "node:tty";
|
|
4
|
+
import { cursor } from "sisteransi";
|
|
5
|
+
export const CANCEL = Symbol("CANCEL");
|
|
6
|
+
export const isWindows = globalThis.process.platform.startsWith("win");
|
|
7
|
+
export function setRawMode(input, value) {
|
|
8
|
+
const i = input;
|
|
9
|
+
if (i.isTTY) i.setRawMode(value);
|
|
10
|
+
}
|
|
11
|
+
export function getColumns(output) {
|
|
12
|
+
if (output instanceof WriteStream && output.columns) {
|
|
13
|
+
return output.columns;
|
|
14
|
+
}
|
|
15
|
+
return 80;
|
|
16
|
+
}
|
|
17
|
+
export function block({
|
|
18
|
+
input = stdin,
|
|
19
|
+
output = stdout,
|
|
20
|
+
overwrite = true,
|
|
21
|
+
hideCursor = true
|
|
22
|
+
} = {}) {
|
|
23
|
+
const rl = readline.createInterface({
|
|
24
|
+
input,
|
|
25
|
+
output,
|
|
26
|
+
prompt: "",
|
|
27
|
+
tabSize: 1
|
|
28
|
+
});
|
|
29
|
+
readline.emitKeypressEvents(input, rl);
|
|
30
|
+
if (input instanceof ReadStream && input.isTTY) {
|
|
31
|
+
input.setRawMode(true);
|
|
32
|
+
}
|
|
33
|
+
const clear = (data, { name, sequence }) => {
|
|
34
|
+
const str = String(data);
|
|
35
|
+
if (str === "" || name === "c" && sequence === "") {
|
|
36
|
+
if (hideCursor) output.write(cursor.show);
|
|
37
|
+
process.exit(0);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (!overwrite) return;
|
|
41
|
+
const dx = name === "return" ? 0 : -1;
|
|
42
|
+
const dy = name === "return" ? -1 : 0;
|
|
43
|
+
readline.moveCursor(output, dx, dy, () => {
|
|
44
|
+
readline.clearLine(output, 1, () => {
|
|
45
|
+
input.once("keypress", clear);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
if (hideCursor) output.write(cursor.hide);
|
|
50
|
+
input.once("keypress", clear);
|
|
51
|
+
return () => {
|
|
52
|
+
input.off("keypress", clear);
|
|
53
|
+
if (hideCursor) output.write(cursor.show);
|
|
54
|
+
if (input instanceof ReadStream && input.isTTY && !isWindows) {
|
|
55
|
+
input.setRawMode(false);
|
|
56
|
+
}
|
|
57
|
+
rl.terminal = false;
|
|
58
|
+
rl.close();
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export function isCancel(value) {
|
|
62
|
+
return value === CANCEL;
|
|
63
|
+
}
|
|
64
|
+
export function cancel(message) {
|
|
65
|
+
if (message) {
|
|
66
|
+
console.log(message);
|
|
67
|
+
}
|
|
68
|
+
process.exit(0);
|
|
69
|
+
}
|
|
70
|
+
export function createCancel() {
|
|
71
|
+
return CANCEL;
|
|
72
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EditorExitResult } from "../../types.js";
|
|
2
|
-
|
|
2
|
+
interface EditorConfig {
|
|
3
3
|
syntaxHighlighting?: boolean;
|
|
4
4
|
theme?: "auto" | "light" | "dark";
|
|
5
5
|
defaultAllowSaveAs?: boolean;
|
|
@@ -7,8 +7,8 @@ type EditorConfig = {
|
|
|
7
7
|
defaultAutoCloseOnSave?: boolean;
|
|
8
8
|
defaultReturnContentOnSave?: boolean;
|
|
9
9
|
[key: string]: any;
|
|
10
|
-
}
|
|
11
|
-
|
|
10
|
+
}
|
|
11
|
+
interface EditorOptions {
|
|
12
12
|
filename?: string | null;
|
|
13
13
|
initialContent?: string | null;
|
|
14
14
|
onSave?: (content: string, filename: string | null) => Promise<string | boolean | undefined> | string | boolean | undefined;
|
|
@@ -20,6 +20,6 @@ type EditorOptions = {
|
|
|
20
20
|
returnContentOnSave?: boolean;
|
|
21
21
|
mode?: string;
|
|
22
22
|
cwd?: string;
|
|
23
|
-
}
|
|
23
|
+
}
|
|
24
24
|
export declare function startEditor(options?: EditorOptions): Promise<EditorExitResult>;
|
|
25
25
|
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Fonts } from "figlet";
|
|
1
2
|
import type { PreventWrongTerminalSizeOptions, PromptOptions } from "../../types.js";
|
|
2
3
|
type StartPromptOptions = PromptOptions & {
|
|
3
4
|
clearConsole?: boolean;
|
|
@@ -12,6 +13,8 @@ type StartPromptOptions = PromptOptions & {
|
|
|
12
13
|
wrongTerminalSize?: boolean;
|
|
13
14
|
windowsHomeDirRoot?: boolean;
|
|
14
15
|
};
|
|
16
|
+
variant?: "header" | "ascii-art";
|
|
17
|
+
asciiArtFont?: Fonts;
|
|
15
18
|
};
|
|
16
|
-
export declare function
|
|
19
|
+
export declare function introPrompt(optionsOrTitle: StartPromptOptions | string): Promise<void>;
|
|
17
20
|
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { relinka } from "@reliverse/relinka";
|
|
2
2
|
import { getCurrentTerminalName } from "@reliverse/runtime";
|
|
3
|
+
import { createAsciiArt } from "../ascii-art/ascii-art.js";
|
|
3
4
|
import { msg } from "../msg-fmt/messages.js";
|
|
4
5
|
import {
|
|
5
6
|
getExactTerminalWidth,
|
|
@@ -12,25 +13,30 @@ import {
|
|
|
12
13
|
preventUnsupportedTTY
|
|
13
14
|
} from "../../utils/prevent.js";
|
|
14
15
|
import { pm, reliversePrompts } from "../../utils/system.js";
|
|
15
|
-
export async function
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
16
|
+
export async function introPrompt(optionsOrTitle) {
|
|
17
|
+
const options = typeof optionsOrTitle === "string" ? { title: optionsOrTitle } : optionsOrTitle;
|
|
18
|
+
const {
|
|
19
|
+
title = "",
|
|
20
|
+
titleColor = "inverse",
|
|
21
|
+
titleTypography = "none",
|
|
22
|
+
titleVariant,
|
|
23
|
+
borderColor = "dim",
|
|
24
|
+
clearConsole = false,
|
|
25
|
+
horizontalLine = true,
|
|
26
|
+
horizontalLineLength: initialHorizontalLineLength = 0,
|
|
27
|
+
packageName = reliversePrompts.name,
|
|
28
|
+
packageVersion = reliversePrompts.version,
|
|
29
|
+
terminalSizeOptions = {},
|
|
30
|
+
isDev = false,
|
|
31
|
+
prevent = {
|
|
32
|
+
unsupportedTTY: true,
|
|
33
|
+
wrongTerminalSize: true,
|
|
34
|
+
windowsHomeDirRoot: true
|
|
35
|
+
},
|
|
36
|
+
variant = "header",
|
|
37
|
+
asciiArtFont
|
|
38
|
+
} = options;
|
|
39
|
+
let horizontalLineLength = initialHorizontalLineLength;
|
|
34
40
|
if (prevent.windowsHomeDirRoot) {
|
|
35
41
|
preventWindowsHomeDirRoot(process.cwd());
|
|
36
42
|
}
|
|
@@ -44,6 +50,14 @@ export async function startPrompt({
|
|
|
44
50
|
const exactTerminalWidth = getExactTerminalWidth();
|
|
45
51
|
const terminalHeight = getTerminalHeight();
|
|
46
52
|
const formattedTitle = title !== "" ? title : `${packageName} v${packageVersion} | ${pm.packageManager} v${pm.version} | ${getCurrentTerminalName()}${isDev && terminalWidth > 80 ? ` | isDev | w${terminalWidth} h${terminalHeight}` : ""}`;
|
|
53
|
+
if (variant === "ascii-art") {
|
|
54
|
+
await createAsciiArt({
|
|
55
|
+
message: formattedTitle,
|
|
56
|
+
font: asciiArtFont,
|
|
57
|
+
clearConsole
|
|
58
|
+
});
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
47
61
|
if (horizontalLineLength === 0) {
|
|
48
62
|
const titleFullLength = titleColor === "inverse" ? `\u2800${formattedTitle}\u2800`.length + 5 : formattedTitle.length + 5;
|
|
49
63
|
horizontalLineLength = Math.max(1, exactTerminalWidth - titleFullLength);
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
export type EmptyArgs = Record<string, never>;
|
|
2
|
-
export
|
|
2
|
+
export interface BaseArgProps {
|
|
3
3
|
description?: string;
|
|
4
4
|
required?: boolean;
|
|
5
5
|
allowed?: string[];
|
|
6
|
-
}
|
|
7
|
-
export
|
|
6
|
+
}
|
|
7
|
+
export interface BaseArgDefinition {
|
|
8
8
|
type: string;
|
|
9
9
|
description?: string;
|
|
10
10
|
required?: boolean;
|
|
11
11
|
default?: any;
|
|
12
12
|
allowed?: any[];
|
|
13
13
|
dependencies?: string[];
|
|
14
|
-
}
|
|
14
|
+
}
|
|
15
15
|
export type PositionalArgDefinition = BaseArgDefinition & {
|
|
16
16
|
type: "positional";
|
|
17
17
|
default?: string;
|
|
@@ -40,13 +40,13 @@ export type ArrayArgDefinition = BaseArgDefinition & {
|
|
|
40
40
|
};
|
|
41
41
|
export type ArgDefinition = PositionalArgDefinition | BooleanArgDefinition | StringArgDefinition | NumberArgDefinition | ArrayArgDefinition;
|
|
42
42
|
export type ArgDefinitions = Record<string, ArgDefinition>;
|
|
43
|
-
export
|
|
43
|
+
export interface CommandMeta {
|
|
44
44
|
name: string;
|
|
45
45
|
version?: string;
|
|
46
46
|
description?: string;
|
|
47
47
|
hidden?: boolean;
|
|
48
48
|
aliases?: string[];
|
|
49
|
-
}
|
|
49
|
+
}
|
|
50
50
|
/**
|
|
51
51
|
* A subcommand can be either:
|
|
52
52
|
* 1) A string path to a module with a default export of type Command.
|
|
@@ -57,13 +57,13 @@ export type CommandSpec = string | (() => Promise<{
|
|
|
57
57
|
default: Command<any>;
|
|
58
58
|
} | Command<any>>);
|
|
59
59
|
export type CommandsMap = Record<string, CommandSpec>;
|
|
60
|
-
export
|
|
60
|
+
export interface CommandContext<ARGS> {
|
|
61
61
|
args: ARGS;
|
|
62
62
|
raw: string[];
|
|
63
|
-
}
|
|
63
|
+
}
|
|
64
64
|
export type CommandRun<ARGS> = (ctx: CommandContext<ARGS>) => void | Promise<void>;
|
|
65
65
|
export type CommandHook<ARGS> = (ctx: CommandContext<ARGS>) => void | Promise<void>;
|
|
66
|
-
export
|
|
66
|
+
export interface DefineCommandOptions<A extends ArgDefinitions = EmptyArgs> {
|
|
67
67
|
meta?: CommandMeta;
|
|
68
68
|
args?: A;
|
|
69
69
|
run?: CommandRun<InferArgTypes<A>>;
|
|
@@ -99,8 +99,8 @@ export type DefineCommandOptions<A extends ArgDefinitions = EmptyArgs> = {
|
|
|
99
99
|
* Called once per CLI process, after all command/run() logic is finished
|
|
100
100
|
*/
|
|
101
101
|
onLauncherExit?: () => void | Promise<void>;
|
|
102
|
-
}
|
|
103
|
-
export
|
|
102
|
+
}
|
|
103
|
+
export interface Command<A extends ArgDefinitions = EmptyArgs> {
|
|
104
104
|
meta?: CommandMeta;
|
|
105
105
|
args: A;
|
|
106
106
|
run?: CommandRun<InferArgTypes<A>>;
|
|
@@ -136,13 +136,13 @@ export type Command<A extends ArgDefinitions = EmptyArgs> = {
|
|
|
136
136
|
* Called once per CLI process, after all command/run() logic is finished
|
|
137
137
|
*/
|
|
138
138
|
onLauncherExit?: () => void | Promise<void>;
|
|
139
|
-
}
|
|
139
|
+
}
|
|
140
140
|
export type InferArgTypes<A extends ArgDefinitions> = {
|
|
141
141
|
[K in keyof A]: A[K] extends PositionalArgDefinition ? string : A[K] extends BooleanArgDefinition ? boolean : A[K] extends StringArgDefinition ? string : A[K] extends NumberArgDefinition ? number : A[K] extends {
|
|
142
142
|
type: "array";
|
|
143
143
|
} ? string[] : never;
|
|
144
144
|
};
|
|
145
|
-
export
|
|
145
|
+
export interface FileBasedCmdsOptions {
|
|
146
146
|
enable: boolean;
|
|
147
147
|
cmdsRootPath: string;
|
|
148
|
-
}
|
|
148
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { TypographyName, ColorName } from "../../types.js";
|
|
2
2
|
import type { VariantName } from "../../types.js";
|
|
3
|
-
|
|
3
|
+
interface NextStepsPromptOptions {
|
|
4
4
|
title?: string;
|
|
5
5
|
titleColor?: ColorName;
|
|
6
6
|
titleVariant?: VariantName;
|
|
@@ -9,6 +9,6 @@ type NextStepsPromptOptions = {
|
|
|
9
9
|
contentColor?: ColorName;
|
|
10
10
|
contentVariant?: VariantName;
|
|
11
11
|
contentTypography?: TypographyName;
|
|
12
|
-
}
|
|
12
|
+
}
|
|
13
13
|
export declare function nextStepsPrompt(options: NextStepsPromptOptions): Promise<void>;
|
|
14
14
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { BorderColorName, ColorName, FmtMsgOptions, TypographyName } from "../../types.js";
|
|
2
2
|
type VariantName = FmtMsgOptions["titleVariant"];
|
|
3
|
-
|
|
3
|
+
interface NumberPromptOptions {
|
|
4
4
|
title: string;
|
|
5
5
|
hint?: string;
|
|
6
6
|
hintPlaceholderColor?: ColorName;
|
|
@@ -23,6 +23,6 @@ type NumberPromptOptions = {
|
|
|
23
23
|
userInput?: string;
|
|
24
24
|
errorMessage?: string;
|
|
25
25
|
};
|
|
26
|
-
}
|
|
26
|
+
}
|
|
27
27
|
export declare function numberPrompt(opts: NumberPromptOptions): Promise<number>;
|
|
28
28
|
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Fonts } from "figlet";
|
|
2
|
+
import type { PromptOptions } from "../../types.js";
|
|
3
|
+
type EndPromptOptions = PromptOptions & {
|
|
4
|
+
variant?: "footer" | "ascii-art";
|
|
5
|
+
asciiArtFont?: Fonts;
|
|
6
|
+
};
|
|
7
|
+
export declare function outroPrompt(optionsOrTitle: EndPromptOptions | string): Promise<void>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { animateText } from "../animate/animate.js";
|
|
2
|
+
import { createAsciiArt } from "../ascii-art/ascii-art.js";
|
|
3
|
+
import { msg } from "../msg-fmt/messages.js";
|
|
4
|
+
import { getExactTerminalWidth } from "../msg-fmt/terminal.js";
|
|
5
|
+
export async function outroPrompt(optionsOrTitle) {
|
|
6
|
+
const options = typeof optionsOrTitle === "string" ? { title: optionsOrTitle } : optionsOrTitle;
|
|
7
|
+
const {
|
|
8
|
+
title = "",
|
|
9
|
+
titleColor = "cyan",
|
|
10
|
+
titleTypography = "none",
|
|
11
|
+
titleVariant,
|
|
12
|
+
titleAnimation,
|
|
13
|
+
titleAnimationDelay,
|
|
14
|
+
border = true,
|
|
15
|
+
borderColor = "dim",
|
|
16
|
+
horizontalLineLength: initialHorizontalLineLength = 0,
|
|
17
|
+
variant = "footer",
|
|
18
|
+
asciiArtFont
|
|
19
|
+
} = options;
|
|
20
|
+
let horizontalLineLength = initialHorizontalLineLength;
|
|
21
|
+
if (variant === "ascii-art") {
|
|
22
|
+
await createAsciiArt({
|
|
23
|
+
message: title || " ",
|
|
24
|
+
font: asciiArtFont
|
|
25
|
+
});
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (horizontalLineLength === 0) {
|
|
29
|
+
horizontalLineLength = getExactTerminalWidth() - 3;
|
|
30
|
+
}
|
|
31
|
+
if (titleAnimation) {
|
|
32
|
+
await animateText({
|
|
33
|
+
title: title ? title : " ",
|
|
34
|
+
anim: titleAnimation,
|
|
35
|
+
delay: titleAnimationDelay,
|
|
36
|
+
type: "M_END",
|
|
37
|
+
titleColor,
|
|
38
|
+
titleTypography,
|
|
39
|
+
border,
|
|
40
|
+
borderColor,
|
|
41
|
+
horizontalLineLength
|
|
42
|
+
});
|
|
43
|
+
} else {
|
|
44
|
+
msg({
|
|
45
|
+
type: "M_END",
|
|
46
|
+
title: title ? title : " ",
|
|
47
|
+
titleColor,
|
|
48
|
+
titleTypography,
|
|
49
|
+
titleVariant,
|
|
50
|
+
border,
|
|
51
|
+
borderColor,
|
|
52
|
+
horizontalLineLength
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|