@reliverse/rempts 1.7.34 → 1.7.36

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 CHANGED
@@ -99,17 +99,19 @@ import {
99
99
 
100
100
  To help you migrate from the different CLI frameworks, `@reliverse/rempts` has some aliases for the most popular prompts.
101
101
 
102
- | Prompt | Aliases |
103
- |-----------------------|-----------------|
104
- | `useSpinner` | `spinner` |
105
- | `selectPrompt` | `select` |
106
- | `multiselectPrompt` | `multiselect` |
107
- | `inputPrompt` | `text`, `input` |
108
- | `@reliverse/relinka` | `log` |
109
-
110
- ### Notices
111
-
112
- - `setup`/`cleanup` are now `onCmdInit`/`onCmdExit` (old names still work for now).
102
+ | Prompt | Aliases |
103
+ |-----------------------|------------------|
104
+ | `createCli` | `runMain` |
105
+ | `onCmdInit` | `setup` |
106
+ | `onCmdExit` | `cleanup` |
107
+ | `useSpinner` | `spinner` |
108
+ | `selectPrompt` | `select` |
109
+ | `multiselectPrompt` | `multiselect` |
110
+ | `inputPrompt` | `text`, `input` |
111
+ | `confirmPrompt` | `confirm` |
112
+ | `introPrompt` | `intro`, `start` |
113
+ | `outroPrompt` | `outro`, `end` |
114
+ | `log` | `relinka` |
113
115
 
114
116
  ### Prompts Usage Example
115
117
 
@@ -84,7 +84,7 @@ export async function confirmPrompt(options) {
84
84
  endTitleColor = "dim",
85
85
  border = true
86
86
  } = options;
87
- const finalTitle = message && title ? `${title}: ${message}` : message ?? title;
87
+ const finalTitle = message && title ? `${title}: ${message}` : message ?? title ?? "Confirm";
88
88
  const finalDefaultValue = defaultValue ?? initialValue;
89
89
  const rl = readline.createInterface({ input, output });
90
90
  let errorMessage = "";
@@ -0,0 +1,33 @@
1
+ export interface GroupOptions {
2
+ onCancel?: () => void;
3
+ showProgress?: boolean;
4
+ title?: string;
5
+ }
6
+ export interface GroupContext<T> {
7
+ results: Partial<T>;
8
+ step: keyof T;
9
+ stepIndex: number;
10
+ totalSteps: number;
11
+ }
12
+ export type GroupStep<T, K extends keyof T> = (context: GroupContext<T>) => Promise<T[K]> | T[K];
13
+ export type GroupSteps<T> = {
14
+ [K in keyof T]: GroupStep<T, K>;
15
+ };
16
+ /**
17
+ * Runs a series of prompts in sequence, where each prompt can depend on the results of previous prompts.
18
+ *
19
+ * @param steps Object where each key is a step name and each value is a function that returns a promise
20
+ * @param options Optional configuration including onCancel callback and progress display
21
+ * @returns Promise resolving to the complete results object
22
+ */
23
+ export declare function group<T extends Record<string, any>>(steps: GroupSteps<T>, options?: GroupOptions): Promise<T>;
24
+ /**
25
+ * Utility function to create a step that depends on specific previous results
26
+ */
27
+ export declare function createStep<T, K extends keyof T, D extends keyof T>(stepFunction: (context: GroupContext<T>, dependency: T[D]) => Promise<T[K]> | T[K], dependencyKey: D): GroupStep<T, K>;
28
+ /**
29
+ * Utility function to create a step that depends on multiple previous results
30
+ */
31
+ export declare function createMultiStep<T, K extends keyof T, D extends (keyof T)[]>(stepFunction: (context: GroupContext<T>, dependencies: {
32
+ [P in D[number]]: T[P];
33
+ }) => Promise<T[K]> | T[K], dependencyKeys: D): GroupStep<T, K>;
@@ -0,0 +1,93 @@
1
+ import { msg } from "../msg-fmt/messages.js";
2
+ export async function group(steps, options = {}) {
3
+ const { showProgress = true, title = "Configuration" } = options;
4
+ const stepKeys = Object.keys(steps);
5
+ const results = {};
6
+ const totalSteps = stepKeys.length;
7
+ if (showProgress && title) {
8
+ msg({
9
+ type: "M_START",
10
+ title,
11
+ titleColor: "cyan",
12
+ titleTypography: "bold"
13
+ });
14
+ }
15
+ for (let stepIndex = 0; stepIndex < stepKeys.length; stepIndex++) {
16
+ const stepKey = stepKeys[stepIndex];
17
+ const stepFunction = steps[stepKey];
18
+ if (showProgress) {
19
+ msg({
20
+ type: "M_MIDDLE",
21
+ title: `Step ${stepIndex + 1}/${totalSteps}: ${String(stepKey)}`,
22
+ titleColor: "dim"
23
+ });
24
+ }
25
+ const context = {
26
+ results,
27
+ step: stepKey,
28
+ stepIndex,
29
+ totalSteps
30
+ };
31
+ try {
32
+ const result = await stepFunction(context);
33
+ results[stepKey] = result;
34
+ if (showProgress) {
35
+ msg({
36
+ type: "M_MIDDLE",
37
+ title: `\u2713 ${String(stepKey)} completed`,
38
+ titleColor: "green"
39
+ });
40
+ }
41
+ } catch (error) {
42
+ if (error instanceof Error && error.message === "CANCEL") {
43
+ if (options.onCancel) {
44
+ options.onCancel();
45
+ }
46
+ throw error;
47
+ }
48
+ if (showProgress) {
49
+ msg({
50
+ type: "M_ERROR",
51
+ title: `\u2717 ${String(stepKey)} failed: ${error instanceof Error ? error.message : String(error)}`,
52
+ titleColor: "red"
53
+ });
54
+ }
55
+ throw error;
56
+ }
57
+ }
58
+ if (showProgress) {
59
+ msg({
60
+ type: "M_END",
61
+ title: `${title} completed successfully!`,
62
+ titleColor: "green",
63
+ titleTypography: "bold"
64
+ });
65
+ }
66
+ return results;
67
+ }
68
+ export function createStep(stepFunction, dependencyKey) {
69
+ return (context) => {
70
+ const dependency = context.results[dependencyKey];
71
+ if (dependency === void 0) {
72
+ throw new Error(
73
+ `Dependency '${String(dependencyKey)}' is required but not available`
74
+ );
75
+ }
76
+ return stepFunction(context, dependency);
77
+ };
78
+ }
79
+ export function createMultiStep(stepFunction, dependencyKeys) {
80
+ return (context) => {
81
+ const dependencies = {};
82
+ for (const key of dependencyKeys) {
83
+ const dependency = context.results[key];
84
+ if (dependency === void 0) {
85
+ throw new Error(
86
+ `Dependency '${String(key)}' is required but not available`
87
+ );
88
+ }
89
+ dependencies[key] = dependency;
90
+ }
91
+ return stepFunction(context, dependencies);
92
+ };
93
+ }
@@ -100,7 +100,7 @@ function renderPromptUI(params) {
100
100
  symbolColor
101
101
  });
102
102
  void streamText({
103
- text: title,
103
+ text: title || "",
104
104
  delay: streamDelay,
105
105
  color: titleColor,
106
106
  newline: false
@@ -229,7 +229,7 @@ export async function inputPrompt(options) {
229
229
  shouldStream = false,
230
230
  streamDelay = 20
231
231
  } = options;
232
- const finalTitle = message && title ? `${title}: ${message}` : message ?? title;
232
+ const finalTitle = message && title ? `${title}: ${message}` : message ?? title ?? "Input";
233
233
  const finalDefaultValue = defaultValue ?? initialValue;
234
234
  const terminal = readline.createInterface({
235
235
  input: process.stdin,
@@ -110,12 +110,14 @@ export async function multiselectPrompt(params) {
110
110
  debug = false,
111
111
  terminalWidth: customTerminalWidth = 90,
112
112
  displayInstructions = false,
113
+ required = false,
113
114
  minSelect = 0,
114
115
  maxSelect,
115
116
  selectAll = false
116
117
  } = params;
117
- const finalTitle = message && title ? `${title}: ${message}` : message ?? title;
118
+ const finalTitle = message && title ? `${title}: ${message}` : message ?? title ?? "Select options";
118
119
  const finalDefaultValue = defaultValue ?? initialValue;
120
+ const effectiveMinSelect = required ? Math.max(1, minSelect) : minSelect;
119
121
  let pointer = finalDefaultValue.length > 0 ? options.findIndex(
120
122
  (opt) => opt && isSelectOption(opt) && finalDefaultValue.includes(opt.value) && !opt.disabled
121
123
  ) : 0;
@@ -257,9 +259,9 @@ export async function multiselectPrompt(params) {
257
259
  }
258
260
  async function confirmSelection() {
259
261
  const selectedCount = selectedOptions.size;
260
- if (selectedCount < minSelect) {
262
+ if (selectedCount < effectiveMinSelect) {
261
263
  deleteLastLine();
262
- errorMessage = `You must select at least ${minSelect} option${minSelect !== 1 ? "s" : ""}.`;
264
+ errorMessage = `You must select at least ${effectiveMinSelect} option${effectiveMinSelect !== 1 ? "s" : ""}.`;
263
265
  renderOptions();
264
266
  return;
265
267
  }
@@ -0,0 +1,9 @@
1
+ import type { SelectPromptParams } from "../../types.js";
2
+ export declare const select: <T extends string>(params: SelectPromptParams<T>) => Promise<T>;
3
+ export declare const selectSimple: <T extends string>(params: Omit<SelectPromptParams<T>, "options"> & {
4
+ options: {
5
+ value: T;
6
+ label?: string;
7
+ hint?: string;
8
+ }[];
9
+ }) => Promise<T>;
@@ -0,0 +1,9 @@
1
+ import { selectPrompt } from "./select-prompt.js";
2
+ export const select = selectPrompt;
3
+ export const selectSimple = (params) => {
4
+ return selectPrompt({
5
+ ...params,
6
+ optionsArray: params.options,
7
+ options: void 0
8
+ });
9
+ };
@@ -114,6 +114,7 @@ export async function selectPrompt(params) {
114
114
  message,
115
115
  content = "",
116
116
  options,
117
+ optionsArray,
117
118
  defaultValue,
118
119
  initialValue,
119
120
  required = false,
@@ -132,13 +133,19 @@ export async function selectPrompt(params) {
132
133
  shouldStream = false,
133
134
  streamDelay = 20
134
135
  } = params;
135
- const finalTitle = message && title ? `${title}: ${message}` : message ?? title;
136
+ const finalTitle = message && title ? `${title}: ${message}` : message ?? title ?? "Select option";
136
137
  const finalDefaultValue = defaultValue ?? initialValue;
137
- let selectedIndex = finalDefaultValue ? options.findIndex(
138
+ const finalOptions = options ?? optionsArray?.map((opt) => ({
139
+ value: opt.value,
140
+ label: opt.label ?? opt.value,
141
+ hint: opt.hint,
142
+ disabled: false
143
+ })) ?? [];
144
+ let selectedIndex = finalDefaultValue ? finalOptions.findIndex(
138
145
  (option) => isSelectOption(option) && option.value === finalDefaultValue && !option.disabled
139
146
  ) : -1;
140
147
  if (selectedIndex === -1) {
141
- selectedIndex = options.findIndex(
148
+ selectedIndex = finalOptions.findIndex(
142
149
  (option) => isSelectOption(option) && !option.disabled
143
150
  );
144
151
  }
@@ -152,7 +159,7 @@ export async function selectPrompt(params) {
152
159
  }
153
160
  const instructions = "Use <\u2191/\u2193> or <k/j> to navigate, <Enter> to select, <Ctrl+C> to exit";
154
161
  let errorMessage = "";
155
- const allDisabled = options.every(
162
+ const allDisabled = finalOptions.every(
156
163
  (option) => isSelectOption(option) && option.disabled
157
164
  );
158
165
  let lastUILineCount = 0;
@@ -165,7 +172,7 @@ export async function selectPrompt(params) {
165
172
  void renderPromptUI({
166
173
  title: finalTitle,
167
174
  content,
168
- options,
175
+ options: finalOptions,
169
176
  selectedIndex,
170
177
  errorMessage,
171
178
  displayInstructions,
@@ -189,7 +196,7 @@ export async function selectPrompt(params) {
189
196
  lastUILineCount = await renderPromptUI({
190
197
  title: finalTitle,
191
198
  content,
192
- options,
199
+ options: finalOptions,
193
200
  selectedIndex,
194
201
  errorMessage,
195
202
  displayInstructions,
@@ -229,8 +236,8 @@ export async function selectPrompt(params) {
229
236
  function moveSelectionUp() {
230
237
  const originalPointer = selectedIndex;
231
238
  do {
232
- selectedIndex = (selectedIndex - 1 + options.length) % options.length;
233
- const option = options[selectedIndex];
239
+ selectedIndex = (selectedIndex - 1 + finalOptions.length) % finalOptions.length;
240
+ const option = finalOptions[selectedIndex];
234
241
  if (option && isSelectOption(option) && !option.disabled) break;
235
242
  } while (selectedIndex !== originalPointer);
236
243
  renderOptions();
@@ -238,14 +245,14 @@ export async function selectPrompt(params) {
238
245
  function moveSelectionDown() {
239
246
  const originalPointer = selectedIndex;
240
247
  do {
241
- selectedIndex = (selectedIndex + 1) % options.length;
242
- const option = options[selectedIndex];
248
+ selectedIndex = (selectedIndex + 1) % finalOptions.length;
249
+ const option = finalOptions[selectedIndex];
243
250
  if (option && isSelectOption(option) && !option.disabled) break;
244
251
  } while (selectedIndex !== originalPointer);
245
252
  renderOptions();
246
253
  }
247
254
  async function confirmSelection() {
248
- const option = options[selectedIndex];
255
+ const option = finalOptions[selectedIndex];
249
256
  if (!option || !isSelectOption(option)) {
250
257
  errorMessage = "This option is not selectable.";
251
258
  renderOptions();
@@ -256,7 +263,7 @@ export async function selectPrompt(params) {
256
263
  renderOptions();
257
264
  return;
258
265
  }
259
- if (required && !option.value) {
266
+ if (required && (!option.value || option.value === "")) {
260
267
  errorMessage = "You must select a valid option.";
261
268
  renderOptions();
262
269
  return;
package/bin/mod.d.ts CHANGED
@@ -7,6 +7,8 @@ export { confirmPrompt } from "./libs/confirm/confirm-mod.js";
7
7
  export { datePrompt } from "./libs/date/date.js";
8
8
  export { startEditor } from "./libs/editor/editor-mod.js";
9
9
  export { mainSymbols, fallbackSymbols, figures, } from "./libs/figures/figures-mod.js";
10
+ export type { GroupOptions, GroupContext, GroupStep, GroupSteps, } from "./libs/group/group-mod.js";
11
+ export { group, createStep, createMultiStep } from "./libs/group/group-mod.js";
10
12
  export { input, text, password } from "./libs/input/input-alias.js";
11
13
  export { inputPrompt } from "./libs/input/input-mod.js";
12
14
  export { startPrompt, intro } from "./libs/intro/intro-alias.js";
@@ -17,7 +19,7 @@ export type { EmptyArgs, BaseArgProps, BaseArgDefinition, PositionalArgDefinitio
17
19
  export { loadCommand } from "./libs/launcher/run-command.js";
18
20
  export { addCompletions } from "./libs/launcher/trpc-orpc-support/completions.js";
19
21
  export { CliValidationError, FailedToExitError, } from "./libs/launcher/trpc-orpc-support/errors.js";
20
- export { TrpcCommand, parseRouter, createRpcCli, z, trpcServer, zod, } from "./libs/launcher/trpc-orpc-support/index.js";
22
+ export { TrpcCommand, parseRouter, createRpcCli, z, } from "./libs/launcher/trpc-orpc-support/index.js";
21
23
  export { flattenedProperties, incompatiblePropertyPairs, getDescription, getSchemaTypes, getEnumChoices, } from "./libs/launcher/trpc-orpc-support/json-schema.js";
22
24
  export type { CommandJSON } from "./libs/launcher/trpc-orpc-support/json.js";
23
25
  export { commandToJSON } from "./libs/launcher/trpc-orpc-support/json.js";
@@ -46,9 +48,9 @@ export { endPrompt, outro } from "./libs/outro/outro-alias.js";
46
48
  export { outroPrompt } from "./libs/outro/outro-mod.js";
47
49
  export type { ResultsType } from "./libs/results/results.js";
48
50
  export { resultPrompt } from "./libs/results/results.js";
49
- export { select } from "./libs/select/aliases-alias.js";
50
51
  export { numMultiSelectPrompt } from "./libs/select/nummultiselect-prompt.js";
51
52
  export { numSelectPrompt } from "./libs/select/numselect-prompt.js";
53
+ export { select, selectSimple } from "./libs/select/select-alias.js";
52
54
  export { selectPrompt } from "./libs/select/select-prompt.js";
53
55
  export { togglePrompt } from "./libs/select/toggle-prompt.js";
54
56
  export { spinner } from "./libs/spinner/spinner-alias.js";
@@ -63,4 +65,4 @@ export { streamText, streamTextBox, streamTextWithSpinner, } from "./libs/utils/
63
65
  export { pm, reliversePrompts } from "./libs/utils/system.js";
64
66
  export { isTerminalInteractive, isValidName, normalizeName, } from "./libs/utils/validate.js";
65
67
  export { createAsciiArt } from "./libs/visual/visual-mod.js";
66
- export type { MsgType, TypographyName, BorderColorName, ColorName, VariantName, MsgConfig, PromptOptions, ChoiceOptions, SelectOption, StandardColor, OutputColor, EditorExitResult, MessageKind, AllKinds, MessageConfig, StreamOptions, ProgressBarOptions, ProgressBar, PromptType, ConfirmPromptOptions, StreamTextOptions, PreventWrongTerminalSizeOptions, InputPromptOptions, RenderParams, SymbolName, Symbols, FmtMsgOptions, TogglePromptParams, SeparatorOption, MultiselectPromptParams, DatePromptOptions, } from "./types.js";
68
+ export type { MsgType, TypographyName, BorderColorName, ColorName, VariantName, MsgConfig, PromptOptions, ChoiceOptions, SelectOption, StandardColor, OutputColor, EditorExitResult, MessageKind, AllKinds, MessageConfig, StreamOptions, ProgressBarOptions, ProgressBar, PromptType, ConfirmPromptOptions, StreamTextOptions, PreventWrongTerminalSizeOptions, InputPromptOptions, RenderParams, SymbolName, Symbols, FmtMsgOptions, TogglePromptParams, SeparatorOption, SelectPromptParams, MultiselectPromptParams, DatePromptOptions, } from "./types.js";
package/bin/mod.js CHANGED
@@ -19,6 +19,7 @@ export {
19
19
  fallbackSymbols,
20
20
  figures
21
21
  } from "./libs/figures/figures-mod.js";
22
+ export { group, createStep, createMultiStep } from "./libs/group/group-mod.js";
22
23
  export { input, text, password } from "./libs/input/input-alias.js";
23
24
  export { inputPrompt } from "./libs/input/input-mod.js";
24
25
  export { startPrompt, intro } from "./libs/intro/intro-alias.js";
@@ -41,9 +42,7 @@ export {
41
42
  TrpcCommand,
42
43
  parseRouter,
43
44
  createRpcCli,
44
- z,
45
- trpcServer,
46
- zod
45
+ z
47
46
  } from "./libs/launcher/trpc-orpc-support/index.js";
48
47
  export {
49
48
  flattenedProperties,
@@ -117,9 +116,9 @@ export { numberPrompt } from "./libs/number/number-mod.js";
117
116
  export { endPrompt, outro } from "./libs/outro/outro-alias.js";
118
117
  export { outroPrompt } from "./libs/outro/outro-mod.js";
119
118
  export { resultPrompt } from "./libs/results/results.js";
120
- export { select } from "./libs/select/aliases-alias.js";
121
119
  export { numMultiSelectPrompt } from "./libs/select/nummultiselect-prompt.js";
122
120
  export { numSelectPrompt } from "./libs/select/numselect-prompt.js";
121
+ export { select, selectSimple } from "./libs/select/select-alias.js";
123
122
  export { selectPrompt } from "./libs/select/select-prompt.js";
124
123
  export { togglePrompt } from "./libs/select/toggle-prompt.js";
125
124
  export { spinner } from "./libs/spinner/spinner-alias.js";
package/bin/types.d.ts CHANGED
@@ -115,7 +115,7 @@ export interface ProgressBar {
115
115
  */
116
116
  export type PromptType = "input" | "inputmasked" | "select" | "multiselect" | "nummultiselect" | "numselect" | "toggle" | "confirm" | "spinner" | "progressbar" | "results" | "nextsteps" | "animatedtext" | "date" | "end";
117
117
  export interface ConfirmPromptOptions {
118
- title: string;
118
+ title?: string;
119
119
  message?: string;
120
120
  defaultValue?: boolean;
121
121
  initialValue?: boolean;
@@ -213,7 +213,7 @@ export type InputPromptOptions = {
213
213
  streamDelay?: number;
214
214
  symbol?: SymbolName;
215
215
  symbolColor?: ColorName;
216
- title: string;
216
+ title?: string;
217
217
  titleColor?: ColorName;
218
218
  titleTypography?: TypographyName;
219
219
  titleVariant?: VariantName;
@@ -235,7 +235,7 @@ export interface RenderParams {
235
235
  placeholder?: string;
236
236
  symbol?: SymbolName;
237
237
  symbolColor?: ColorName;
238
- title: string;
238
+ title?: string;
239
239
  titleColor?: ColorName;
240
240
  titleTypography?: TypographyName;
241
241
  titleVariant?: VariantName;
@@ -285,10 +285,12 @@ export interface FmtMsgOptions {
285
285
  noNewLine?: boolean;
286
286
  }
287
287
  export interface TogglePromptParams<T extends string> {
288
- title: string;
288
+ title?: string;
289
+ message?: string;
289
290
  content?: string;
290
291
  options?: [T, T];
291
292
  defaultValue?: T;
293
+ initialValue?: T;
292
294
  borderColor?: BorderColorName;
293
295
  titleColor?: ColorName;
294
296
  titleTypography?: TypographyName;
@@ -310,7 +312,12 @@ export interface SelectPromptParams<T extends string> {
310
312
  title?: string;
311
313
  message?: string;
312
314
  content?: string;
313
- options: (SelectOption<T> | SeparatorOption)[];
315
+ options?: (SelectOption<T> | SeparatorOption)[];
316
+ optionsArray?: {
317
+ value: T;
318
+ label?: string;
319
+ hint?: string;
320
+ }[];
314
321
  defaultValue?: T;
315
322
  initialValue?: T;
316
323
  required?: boolean;
@@ -330,7 +337,7 @@ export interface SelectPromptParams<T extends string> {
330
337
  streamDelay?: number;
331
338
  }
332
339
  export interface MultiselectPromptParams<T extends string> {
333
- title: string;
340
+ title?: string;
334
341
  message?: string;
335
342
  content?: string;
336
343
  options: (SelectOption<T> | SeparatorOption)[];
@@ -348,6 +355,7 @@ export interface MultiselectPromptParams<T extends string> {
348
355
  debug?: boolean;
349
356
  terminalWidth?: number;
350
357
  displayInstructions?: boolean;
358
+ required?: boolean;
351
359
  minSelect?: number;
352
360
  maxSelect?: number;
353
361
  selectAll?: boolean;
package/package.json CHANGED
@@ -44,7 +44,7 @@
44
44
  "license": "MIT",
45
45
  "name": "@reliverse/rempts",
46
46
  "type": "module",
47
- "version": "1.7.34",
47
+ "version": "1.7.36",
48
48
  "author": "reliverse",
49
49
  "bugs": {
50
50
  "email": "blefnk@gmail.com",
@@ -1,2 +0,0 @@
1
- import type { SelectPromptParams } from "../../types.js";
2
- export declare const select: <T extends string>(params: SelectPromptParams<T>) => Promise<T>;
@@ -1,2 +0,0 @@
1
- import { selectPrompt } from "./select-prompt.js";
2
- export const select = selectPrompt;