@reliverse/rempts 1.7.65 → 2.2.7

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 (131) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +1534 -1431
  3. package/cleanup.mjs +33 -0
  4. package/dist/cancel.d.ts +31 -0
  5. package/dist/cancel.js +28 -0
  6. package/dist/ffi.d.ts +1 -0
  7. package/dist/ffi.js +165 -0
  8. package/dist/group.d.ts +16 -0
  9. package/dist/group.js +22 -0
  10. package/dist/launcher/command.d.ts +8 -0
  11. package/dist/launcher/command.js +10 -0
  12. package/dist/launcher/discovery.d.ts +3 -0
  13. package/dist/launcher/discovery.js +207 -0
  14. package/dist/launcher/errors.d.ts +15 -0
  15. package/dist/launcher/errors.js +31 -0
  16. package/dist/launcher/help.d.ts +3 -0
  17. package/dist/launcher/help.js +145 -0
  18. package/dist/launcher/mod.d.ts +12 -0
  19. package/dist/launcher/mod.js +222 -0
  20. package/dist/launcher/parser.d.ts +14 -0
  21. package/dist/launcher/parser.js +255 -0
  22. package/dist/launcher/registry.d.ts +10 -0
  23. package/dist/launcher/registry.js +42 -0
  24. package/dist/launcher/types.d.ts +78 -0
  25. package/dist/launcher/validator.d.ts +3 -0
  26. package/dist/launcher/validator.js +39 -0
  27. package/dist/mod.d.ts +6 -0
  28. package/dist/mod.js +6 -0
  29. package/dist/prompt.d.ts +13 -0
  30. package/dist/prompt.js +53 -0
  31. package/dist/selection.d.ts +92 -0
  32. package/dist/selection.js +191 -0
  33. package/dist/spinner.d.ts +26 -0
  34. package/dist/spinner.js +141 -0
  35. package/dist/utils.d.ts +3 -0
  36. package/dist/utils.js +11 -0
  37. package/package.json +41 -47
  38. package/bin/libs/animate/animate-mod.ts.txt +0 -78
  39. package/bin/libs/anykey/anykey-mod.d.ts +0 -12
  40. package/bin/libs/anykey/anykey-mod.js +0 -125
  41. package/bin/libs/cancel/cancel.d.ts +0 -45
  42. package/bin/libs/cancel/cancel.js +0 -72
  43. package/bin/libs/confirm/confirm-alias.d.ts +0 -2
  44. package/bin/libs/confirm/confirm-alias.js +0 -2
  45. package/bin/libs/confirm/confirm-mod.d.ts +0 -5
  46. package/bin/libs/confirm/confirm-mod.js +0 -179
  47. package/bin/libs/date/date.d.ts +0 -2
  48. package/bin/libs/date/date.js +0 -254
  49. package/bin/libs/editor/editor-mod.d.ts +0 -25
  50. package/bin/libs/editor/editor-mod.js +0 -1133
  51. package/bin/libs/figures/figures-mod.d.ts +0 -461
  52. package/bin/libs/figures/figures-mod.js +0 -285
  53. package/bin/libs/group/group-mod.d.ts +0 -33
  54. package/bin/libs/group/group-mod.js +0 -89
  55. package/bin/libs/input/input-alias.d.ts +0 -5
  56. package/bin/libs/input/input-alias.js +0 -4
  57. package/bin/libs/input/input-mod.d.ts +0 -16
  58. package/bin/libs/input/input-mod.js +0 -370
  59. package/bin/libs/intro/intro-alias.d.ts +0 -3
  60. package/bin/libs/intro/intro-alias.js +0 -3
  61. package/bin/libs/intro/intro-mod.d.ts +0 -19
  62. package/bin/libs/intro/intro-mod.js +0 -71
  63. package/bin/libs/launcher/command-runner.d.ts +0 -31
  64. package/bin/libs/launcher/command-runner.js +0 -229
  65. package/bin/libs/launcher/launcher-alias.d.ts +0 -2
  66. package/bin/libs/launcher/launcher-alias.js +0 -2
  67. package/bin/libs/launcher/launcher-mod.d.ts +0 -66
  68. package/bin/libs/launcher/launcher-mod.js +0 -1037
  69. package/bin/libs/launcher/launcher-types.d.ts +0 -176
  70. package/bin/libs/launcher/launcher-types.js +0 -0
  71. package/bin/libs/log/log-alias.d.ts +0 -1
  72. package/bin/libs/log/log-alias.js +0 -2
  73. package/bin/libs/msg-fmt/colors.d.ts +0 -30
  74. package/bin/libs/msg-fmt/colors.js +0 -42
  75. package/bin/libs/msg-fmt/mapping.d.ts +0 -3
  76. package/bin/libs/msg-fmt/mapping.js +0 -41
  77. package/bin/libs/msg-fmt/messages.d.ts +0 -35
  78. package/bin/libs/msg-fmt/messages.js +0 -305
  79. package/bin/libs/msg-fmt/terminal.d.ts +0 -15
  80. package/bin/libs/msg-fmt/terminal.js +0 -60
  81. package/bin/libs/msg-fmt/variants.d.ts +0 -11
  82. package/bin/libs/msg-fmt/variants.js +0 -52
  83. package/bin/libs/multiselect/multiselect-alias.d.ts +0 -2
  84. package/bin/libs/multiselect/multiselect-alias.js +0 -2
  85. package/bin/libs/multiselect/multiselect-prompt.d.ts +0 -2
  86. package/bin/libs/multiselect/multiselect-prompt.js +0 -340
  87. package/bin/libs/next-steps/next-steps.d.ts +0 -13
  88. package/bin/libs/next-steps/next-steps.js +0 -24
  89. package/bin/libs/number/number-mod.d.ts +0 -28
  90. package/bin/libs/number/number-mod.js +0 -234
  91. package/bin/libs/outro/outro-alias.d.ts +0 -3
  92. package/bin/libs/outro/outro-alias.js +0 -3
  93. package/bin/libs/outro/outro-mod.d.ts +0 -7
  94. package/bin/libs/outro/outro-mod.js +0 -49
  95. package/bin/libs/reliarg/reliarg-mod.d.ts +0 -76
  96. package/bin/libs/reliarg/reliarg-mod.js +0 -276
  97. package/bin/libs/results/results.d.ts +0 -7
  98. package/bin/libs/results/results.js +0 -27
  99. package/bin/libs/select/nummultiselect-prompt.d.ts +0 -6
  100. package/bin/libs/select/nummultiselect-prompt.js +0 -141
  101. package/bin/libs/select/numselect-prompt.d.ts +0 -7
  102. package/bin/libs/select/numselect-prompt.js +0 -111
  103. package/bin/libs/select/select-alias.d.ts +0 -9
  104. package/bin/libs/select/select-alias.js +0 -9
  105. package/bin/libs/select/select-prompt.d.ts +0 -5
  106. package/bin/libs/select/select-prompt.js +0 -311
  107. package/bin/libs/select/toggle-prompt.d.ts +0 -5
  108. package/bin/libs/select/toggle-prompt.js +0 -207
  109. package/bin/libs/spinner/spinner-impl.d.ts +0 -70
  110. package/bin/libs/spinner/spinner-impl.js +0 -336
  111. package/bin/libs/spinner/spinner-mod.d.ts +0 -167
  112. package/bin/libs/spinner/spinner-mod.js +0 -447
  113. package/bin/libs/utils/colorize.d.ts +0 -2
  114. package/bin/libs/utils/colorize.js +0 -122
  115. package/bin/libs/utils/errors.d.ts +0 -1
  116. package/bin/libs/utils/errors.js +0 -17
  117. package/bin/libs/utils/prevent.d.ts +0 -8
  118. package/bin/libs/utils/prevent.js +0 -62
  119. package/bin/libs/utils/prompt-end.d.ts +0 -8
  120. package/bin/libs/utils/prompt-end.js +0 -36
  121. package/bin/libs/utils/stream-text.d.ts +0 -18
  122. package/bin/libs/utils/stream-text.js +0 -138
  123. package/bin/libs/utils/system.d.ts +0 -6
  124. package/bin/libs/utils/system.js +0 -7
  125. package/bin/libs/utils/validate.d.ts +0 -21
  126. package/bin/libs/utils/validate.js +0 -17
  127. package/bin/libs/visual/visual-mod.ts.txt +0 -19
  128. package/bin/mod.d.ts +0 -50
  129. package/bin/mod.js +0 -127
  130. package/bin/types.d.ts +0 -372
  131. /package/{bin → dist/launcher}/types.js +0 -0
@@ -0,0 +1,42 @@
1
+ let cachedRegistry = null;
2
+ export const getRegistry = () => cachedRegistry;
3
+ export const setRegistry = (registry) => {
4
+ cachedRegistry = registry;
5
+ };
6
+ export const clearRegistry = () => {
7
+ cachedRegistry = null;
8
+ };
9
+ export const resolveCommand = (registry, cmdNameOrAlias) => {
10
+ const resolvedName = registry.aliases.get(cmdNameOrAlias) ?? cmdNameOrAlias;
11
+ return resolvedName;
12
+ };
13
+ export const resolveCommandChain = (registry, cmdChain) => {
14
+ if (cmdChain.length === 0) {
15
+ throw new Error("Empty command chain");
16
+ }
17
+ if (cmdChain.length === 1) {
18
+ const cmdName = resolveCommand(registry, cmdChain[0]);
19
+ const node = registry.hierarchy.get(cmdName);
20
+ if (!node) {
21
+ throw new Error(`Command not found: ${cmdChain[0]}`);
22
+ }
23
+ return { fullPath: [cmdName] };
24
+ }
25
+ const parentName = resolveCommand(registry, cmdChain[0]);
26
+ const childName = resolveCommand(registry, cmdChain[1]);
27
+ const parentNode = registry.hierarchy.get(parentName);
28
+ const childNode = registry.hierarchy.get(childName);
29
+ if (!parentNode) {
30
+ throw new Error(`Parent command not found: ${cmdChain[0]}`);
31
+ }
32
+ if (!childNode || childNode.parent !== parentName) {
33
+ throw new Error(
34
+ `Sub-command not found: ${cmdChain[1]} under ${cmdChain[0]}`
35
+ );
36
+ }
37
+ return {
38
+ parent: parentNode,
39
+ child: childNode,
40
+ fullPath: [parentName, childName]
41
+ };
42
+ };
@@ -0,0 +1,78 @@
1
+ interface BaseArg {
2
+ description?: string;
3
+ aliases?: string[];
4
+ positional?: boolean;
5
+ }
6
+ type StringArg = BaseArg & {
7
+ type: "string";
8
+ required?: boolean;
9
+ default?: string;
10
+ allowed?: string[];
11
+ validate?: (value: string) => boolean | string;
12
+ };
13
+ type BooleanArg = BaseArg & {
14
+ type: "boolean";
15
+ required?: boolean;
16
+ default?: boolean;
17
+ allowed?: boolean[];
18
+ };
19
+ type NumberArg = BaseArg & {
20
+ type: "number";
21
+ required?: boolean;
22
+ default?: number;
23
+ allowed?: number[];
24
+ validate?: (value: number) => boolean | string;
25
+ };
26
+ export type CmdArgDefinition = StringArg | BooleanArg | NumberArg;
27
+ export type CmdArgsSchema = Record<string, CmdArgDefinition>;
28
+ export interface CmdMeta {
29
+ name: string;
30
+ description?: string;
31
+ version?: string;
32
+ aliases?: string[];
33
+ examples?: string[];
34
+ }
35
+ export interface CmdDefinition<T extends CmdArgsSchema = CmdArgsSchema> {
36
+ handler: CmdHandler<T>;
37
+ args: T;
38
+ meta: CmdMeta;
39
+ }
40
+ export type CmdHandler<T extends CmdArgsSchema = CmdArgsSchema> = (context: {
41
+ args: ParsedArgs<T>;
42
+ parentArgs?: ParsedArgs<any>;
43
+ }) => Promise<void> | void;
44
+ type InferArgType<T extends CmdArgDefinition> = T["type"] extends "string" ? string : T["type"] extends "number" ? number : boolean;
45
+ type InferArgValue<T extends CmdArgDefinition> = T extends {
46
+ required: true;
47
+ } ? InferArgType<T> : T extends {
48
+ default: any;
49
+ } ? InferArgType<T> : InferArgType<T> | undefined;
50
+ export type ParsedArgs<T extends CmdArgsSchema> = {
51
+ [K in keyof T]: InferArgValue<T[K]>;
52
+ };
53
+ export type CmdLoader = () => Promise<CmdDefinition>;
54
+ export type CmdRegistry = Map<string, CmdLoader>;
55
+ export interface CmdMetadata {
56
+ name: string;
57
+ description?: string;
58
+ aliases?: string[];
59
+ version?: string;
60
+ examples?: string[];
61
+ }
62
+ export interface CmdNode {
63
+ name: string;
64
+ path: string;
65
+ depth: number;
66
+ parent?: string;
67
+ children: Map<string, CmdNode>;
68
+ loader: CmdLoader;
69
+ metadata: () => Promise<CmdMetadata>;
70
+ }
71
+ export interface DiscoveryResult {
72
+ registry: CmdRegistry;
73
+ aliases: Map<string, string>;
74
+ metadata: Map<string, () => Promise<CmdMetadata>>;
75
+ hierarchy: Map<string, CmdNode>;
76
+ rootCommands: Set<string>;
77
+ }
78
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { CmdArgDefinition, CmdArgsSchema } from "./types.js";
2
+ export declare const validateArgValue: (argName: string, value: unknown, definition: CmdArgDefinition) => boolean;
3
+ export declare const validateRequiredArgs: (args: Record<string, unknown>, schema: CmdArgsSchema) => void;
@@ -0,0 +1,39 @@
1
+ import { ArgumentValidationError } from "./errors.js";
2
+ export const validateArgValue = (argName, value, definition) => {
3
+ const expectedType = definition.type === "boolean" ? "boolean" : definition.type === "number" ? "number" : "string";
4
+ if (typeof value !== expectedType) {
5
+ throw new ArgumentValidationError(
6
+ argName,
7
+ `Expected ${expectedType}, got ${typeof value}`
8
+ );
9
+ }
10
+ if ("allowed" in definition && definition.allowed) {
11
+ if (!definition.allowed.includes(value)) {
12
+ const allowedValues = definition.allowed.map((v) => typeof v === "string" ? `"${v}"` : String(v)).join(", ");
13
+ throw new ArgumentValidationError(
14
+ argName,
15
+ `Value must be one of: ${allowedValues}. Got: ${typeof value === "string" ? `"${value}"` : value}`
16
+ );
17
+ }
18
+ }
19
+ if ("validate" in definition && definition.validate) {
20
+ const result = definition.validate(value);
21
+ if (result !== true) {
22
+ throw new ArgumentValidationError(
23
+ argName,
24
+ typeof result === "string" ? result : "Validation failed"
25
+ );
26
+ }
27
+ }
28
+ return true;
29
+ };
30
+ export const validateRequiredArgs = (args, schema) => {
31
+ for (const [key, def] of Object.entries(schema)) {
32
+ if (def.required && !(key in args)) {
33
+ throw new ArgumentValidationError(
34
+ key,
35
+ `Required argument "${key}" is missing`
36
+ );
37
+ }
38
+ }
39
+ };
package/dist/mod.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export * from "./cancel.js";
2
+ export * from "./group.js";
3
+ export * from "./launcher/mod.js";
4
+ export * from "./prompt.js";
5
+ export * from "./selection.js";
6
+ export * from "./spinner.js";
package/dist/mod.js ADDED
@@ -0,0 +1,6 @@
1
+ export * from "./cancel.js";
2
+ export * from "./group.js";
3
+ export * from "./launcher/mod.js";
4
+ export * from "./prompt.js";
5
+ export * from "./selection.js";
6
+ export * from "./spinner.js";
@@ -0,0 +1,13 @@
1
+ export type InputPromptOptions = {
2
+ message: string;
3
+ title?: string;
4
+ charLimit?: number;
5
+ required?: boolean;
6
+ echoMode?: "normal" | "password" | "none";
7
+ validateOkPrefix?: string;
8
+ validateErrPrefix?: string;
9
+ defaultValue?: string;
10
+ initialValue?: string;
11
+ validate?: (value: string) => boolean | string | null | undefined;
12
+ };
13
+ export declare function inputPrompt(options: InputPromptOptions): Promise<string>;
package/dist/prompt.js ADDED
@@ -0,0 +1,53 @@
1
+ import { ptr } from "bun:ffi";
2
+ import { cancel } from "./cancel.js";
3
+ import { symbols } from "./ffi.js";
4
+ import { encode, toStringFromPtr } from "./utils.js";
5
+ function formatPromptText(title, message) {
6
+ if (title && message) {
7
+ return `${title}
8
+ \x1B[2m${message}\x1B[0m`;
9
+ }
10
+ return message ?? title ?? "";
11
+ }
12
+ export async function inputPrompt(options) {
13
+ const defaultValue = options.defaultValue;
14
+ const initialValue = options.initialValue;
15
+ const originalPromptText = formatPromptText(options.title, options.message);
16
+ let promptText = originalPromptText;
17
+ let currentDefaultValue = defaultValue;
18
+ let currentInitialValue = initialValue;
19
+ while (true) {
20
+ const returnedPtr = symbols.CreatePrompt(
21
+ ptr(encode(promptText)),
22
+ ptr(encode(options.echoMode || "normal")),
23
+ ptr(encode(options.validateOkPrefix || "")),
24
+ ptr(encode(options.validateErrPrefix || "")),
25
+ ptr(encode(currentDefaultValue || "")),
26
+ ptr(encode(currentInitialValue || "")),
27
+ options.required ?? true,
28
+ options.charLimit || 0
29
+ );
30
+ const { value, error } = JSON.parse(toStringFromPtr(returnedPtr));
31
+ if (error !== "") {
32
+ if (error === "Cancelled") {
33
+ if (options.required ?? true) {
34
+ cancel(error);
35
+ }
36
+ return "";
37
+ }
38
+ throw new Error(error);
39
+ }
40
+ if (!options.validate) {
41
+ return value;
42
+ }
43
+ const validationResult = options.validate(value);
44
+ if (validationResult === true || validationResult === null || validationResult === void 0) {
45
+ return value;
46
+ }
47
+ const errorMessage = typeof validationResult === "string" ? validationResult : "Invalid input";
48
+ promptText = `${originalPromptText}
49
+ \u274C ${errorMessage}`;
50
+ currentDefaultValue = void 0;
51
+ currentInitialValue = void 0;
52
+ }
53
+ }
@@ -0,0 +1,92 @@
1
+ export type SelectionItem<T extends string = string> = {
2
+ value: T;
3
+ label: string;
4
+ hint?: string;
5
+ disabled?: boolean;
6
+ };
7
+ type ExtractValues<T extends readonly SelectionItem[]> = T[number]["value"];
8
+ export type SelectPromptOptions<TOptions extends readonly SelectionItem[] = SelectionItem[]> = {
9
+ message: string;
10
+ title?: string;
11
+ options: TOptions;
12
+ perPage?: number;
13
+ headerText?: string;
14
+ footerText?: string;
15
+ required?: boolean;
16
+ autocomplete?: boolean;
17
+ defaultValue?: string;
18
+ initialValue?: string;
19
+ };
20
+ export type MultiselectPromptOptions<TOptions extends readonly SelectionItem[] = SelectionItem[]> = {
21
+ message: string;
22
+ title?: string;
23
+ options: TOptions;
24
+ perPage?: number;
25
+ headerText?: string;
26
+ footerText?: string;
27
+ required?: boolean;
28
+ autocomplete?: boolean;
29
+ defaultValue?: string[];
30
+ initialValue?: string[];
31
+ };
32
+ export type ConfirmPromptOptions = {
33
+ message: string;
34
+ title?: string;
35
+ headerText?: string;
36
+ footerText?: string;
37
+ required?: boolean;
38
+ defaultValue?: boolean;
39
+ initialValue?: boolean;
40
+ };
41
+ export declare function selectPrompt<T extends string>(options: SelectPromptOptions<readonly SelectionItem<T>[]> & {
42
+ required: false;
43
+ }): Promise<T | null>;
44
+ export declare function selectPrompt<T extends string>(options: SelectPromptOptions<readonly SelectionItem<T>[]> & {
45
+ required?: true;
46
+ }): Promise<T>;
47
+ export declare function selectPrompt<const TOptions extends readonly SelectionItem[]>(options: SelectPromptOptions<TOptions> & {
48
+ required: false;
49
+ }): Promise<ExtractValues<TOptions> | null>;
50
+ export declare function selectPrompt<const TOptions extends readonly SelectionItem[]>(options: SelectPromptOptions<TOptions> & {
51
+ required?: true;
52
+ }): Promise<ExtractValues<TOptions>>;
53
+ export declare function multiselectPrompt<T extends string>(options: MultiselectPromptOptions<readonly SelectionItem<T>[]> & {
54
+ required: false;
55
+ }): Promise<T[] | null>;
56
+ export declare function multiselectPrompt<T extends string>(options: MultiselectPromptOptions<readonly SelectionItem<T>[]> & {
57
+ required?: true;
58
+ }): Promise<T[]>;
59
+ export declare function multiselectPrompt<const TOptions extends readonly SelectionItem[]>(options: MultiselectPromptOptions<TOptions> & {
60
+ required: false;
61
+ }): Promise<ExtractValues<TOptions>[] | null>;
62
+ export declare function multiselectPrompt<const TOptions extends readonly SelectionItem[]>(options: MultiselectPromptOptions<TOptions> & {
63
+ required?: true;
64
+ }): Promise<ExtractValues<TOptions>[]>;
65
+ export declare function confirmPrompt(options: ConfirmPromptOptions): Promise<boolean>;
66
+ export type GroupMultiselectPromptOptions<TOptions extends Record<string, readonly SelectionItem[]> = Record<string, readonly SelectionItem[]>> = {
67
+ message: string;
68
+ title?: string;
69
+ options: TOptions;
70
+ perPage?: number;
71
+ headerText?: string;
72
+ footerText?: string;
73
+ required?: boolean;
74
+ autocomplete?: boolean;
75
+ defaultValue?: string[];
76
+ initialValue?: string[];
77
+ selectableGroups?: boolean;
78
+ groupSpacing?: number;
79
+ };
80
+ export declare function groupMultiselectPrompt<T extends string>(options: GroupMultiselectPromptOptions<Record<string, readonly SelectionItem<T>[]>> & {
81
+ required: false;
82
+ }): Promise<T[] | null>;
83
+ export declare function groupMultiselectPrompt<T extends string>(options: GroupMultiselectPromptOptions<Record<string, readonly SelectionItem<T>[]>> & {
84
+ required?: true;
85
+ }): Promise<T[]>;
86
+ export declare function groupMultiselectPrompt<const TOptions extends Record<string, readonly SelectionItem[]>>(options: GroupMultiselectPromptOptions<TOptions> & {
87
+ required: false;
88
+ }): Promise<ExtractValues<TOptions[keyof TOptions]>[] | null>;
89
+ export declare function groupMultiselectPrompt<const TOptions extends Record<string, readonly SelectionItem[]>>(options: GroupMultiselectPromptOptions<TOptions> & {
90
+ required?: true;
91
+ }): Promise<ExtractValues<TOptions[keyof TOptions]>[]>;
92
+ export {};
@@ -0,0 +1,191 @@
1
+ import { ptr } from "bun:ffi";
2
+ import { cancel } from "./cancel.js";
3
+ import { symbols } from "./ffi.js";
4
+ import { encode, toStringFromPtr } from "./utils.js";
5
+ function formatPromptText(title, message) {
6
+ if (title && message) {
7
+ return `${title}
8
+ \x1B[2m${message}\x1B[0m`;
9
+ }
10
+ return message ?? title ?? "";
11
+ }
12
+ export async function selectPrompt(options) {
13
+ const stringifiedItems = JSON.stringify(
14
+ options.options.map((item) => {
15
+ return {
16
+ value: item.value,
17
+ label: item.label,
18
+ hint: item.hint ?? "",
19
+ disabled: item.disabled ?? false
20
+ };
21
+ })
22
+ );
23
+ const headerText = options.headerText || formatPromptText(options.title, options.message) || "Select an item: ";
24
+ const returnedPtr = symbols.CreateSelection(
25
+ ptr(encode(stringifiedItems)),
26
+ ptr(encode(headerText)),
27
+ ptr(encode(options.footerText || "")),
28
+ options.perPage || 5,
29
+ options.autocomplete ?? true,
30
+ ptr(encode(options.defaultValue || "")),
31
+ ptr(encode(options.initialValue || ""))
32
+ );
33
+ const { selectedIndex, error } = JSON.parse(toStringFromPtr(returnedPtr));
34
+ if (error !== "") {
35
+ if (error === "Cancelled") {
36
+ if (options.required ?? true) {
37
+ cancel(error);
38
+ }
39
+ return null;
40
+ }
41
+ throw new Error(error);
42
+ }
43
+ const index = Number(selectedIndex);
44
+ const selectedOption = options.options[index];
45
+ if (!selectedOption) {
46
+ throw new Error("Invalid selection index");
47
+ }
48
+ return selectedOption.value;
49
+ }
50
+ export async function multiselectPrompt(options) {
51
+ const stringifiedItems = JSON.stringify(
52
+ options.options.map((item) => {
53
+ return {
54
+ value: item.value,
55
+ label: item.label,
56
+ hint: item.hint ?? "",
57
+ disabled: item.disabled ?? false
58
+ };
59
+ })
60
+ );
61
+ const headerText = options.headerText || formatPromptText(options.title, options.message) || "Select items: ";
62
+ const preselectedValues = options.initialValue ?? options.defaultValue ?? [];
63
+ const preselectedValuesJson = JSON.stringify(preselectedValues);
64
+ const initialCursorValue = preselectedValues.length > 0 ? preselectedValues[0] : "";
65
+ const returnedPtr = symbols.CreateMultiselect(
66
+ ptr(encode(stringifiedItems)),
67
+ ptr(encode(headerText)),
68
+ ptr(encode(options.footerText || "")),
69
+ options.perPage || 5,
70
+ options.autocomplete ?? true,
71
+ ptr(encode(preselectedValuesJson)),
72
+ ptr(encode(initialCursorValue))
73
+ );
74
+ const { selectedIndices, error } = JSON.parse(
75
+ toStringFromPtr(returnedPtr)
76
+ );
77
+ if (error !== "") {
78
+ if (error === "Cancelled") {
79
+ if (options.required ?? true) {
80
+ cancel(error);
81
+ }
82
+ return null;
83
+ }
84
+ throw new Error(error);
85
+ }
86
+ const indices = selectedIndices.map((idx) => Number(idx));
87
+ const values = indices.map((index) => options.options[index]?.value).filter((value) => value !== void 0);
88
+ if (values.length !== indices.length) {
89
+ throw new Error("Invalid selection indices");
90
+ }
91
+ return values;
92
+ }
93
+ export async function confirmPrompt(options) {
94
+ const promptText = formatPromptText(options.title, options.message);
95
+ const defaultValue = options.defaultValue !== void 0 ? String(options.defaultValue) : "";
96
+ const initialValue = options.initialValue !== void 0 ? String(options.initialValue) : "";
97
+ const returnedPtr = symbols.CreateConfirm(
98
+ ptr(encode(promptText)),
99
+ ptr(encode(options.headerText || "")),
100
+ ptr(encode(options.footerText || "")),
101
+ ptr(encode(defaultValue)),
102
+ ptr(encode(initialValue))
103
+ );
104
+ const { confirmed, error } = JSON.parse(toStringFromPtr(returnedPtr));
105
+ if (error !== "") {
106
+ if (error === "Cancelled") {
107
+ if (options.required ?? true) {
108
+ cancel(error);
109
+ }
110
+ return options.defaultValue ?? false;
111
+ }
112
+ throw new Error(error);
113
+ }
114
+ if (confirmed === "") {
115
+ throw new Error("No confirmation received");
116
+ }
117
+ return confirmed === "true";
118
+ }
119
+ export async function groupMultiselectPrompt(options) {
120
+ const flattenedItems = [];
121
+ const valueToIndexMap = /* @__PURE__ */ new Map();
122
+ for (const [groupName, groupItems] of Object.entries(options.options)) {
123
+ flattenedItems.push({
124
+ value: `__group__${groupName}`,
125
+ label: groupName,
126
+ hint: "",
127
+ disabled: false,
128
+ isGroupHeader: true,
129
+ groupName
130
+ });
131
+ for (const item of groupItems) {
132
+ const index = flattenedItems.length;
133
+ valueToIndexMap.set(item.value, index);
134
+ flattenedItems.push({
135
+ ...item,
136
+ isGroupHeader: false,
137
+ groupName
138
+ });
139
+ }
140
+ }
141
+ const stringifiedItems = JSON.stringify(
142
+ flattenedItems.map((item) => {
143
+ return {
144
+ value: item.value,
145
+ label: item.label,
146
+ hint: item.hint ?? "",
147
+ disabled: item.disabled ?? false,
148
+ isGroupHeader: item.isGroupHeader,
149
+ groupName: item.groupName
150
+ };
151
+ })
152
+ );
153
+ const headerText = options.headerText || formatPromptText(options.title, options.message) || "Select items: ";
154
+ const preselectedValues = options.initialValue ?? options.defaultValue ?? [];
155
+ const preselectedValuesJson = JSON.stringify(preselectedValues);
156
+ const initialCursorValue = preselectedValues.length > 0 ? preselectedValues[0] : "";
157
+ const returnedPtr = symbols.CreateGroupMultiselect(
158
+ ptr(encode(stringifiedItems)),
159
+ ptr(encode(headerText)),
160
+ ptr(encode(options.footerText || "")),
161
+ options.perPage || 5,
162
+ options.autocomplete ?? true,
163
+ options.selectableGroups ?? false,
164
+ ptr(encode(preselectedValuesJson)),
165
+ ptr(encode(initialCursorValue)),
166
+ options.groupSpacing ?? 0
167
+ );
168
+ const { selectedIndices, error } = JSON.parse(
169
+ toStringFromPtr(returnedPtr)
170
+ );
171
+ if (error !== "") {
172
+ if (error === "Cancelled") {
173
+ if (options.required ?? true) {
174
+ cancel(error);
175
+ }
176
+ return null;
177
+ }
178
+ throw new Error(error);
179
+ }
180
+ const indices = selectedIndices.map((idx) => Number(idx));
181
+ const values = indices.map((index) => {
182
+ const item = flattenedItems[index];
183
+ return item && !item.isGroupHeader ? item.value : void 0;
184
+ }).filter(
185
+ (value) => value !== void 0
186
+ );
187
+ if (values.length !== indices.length) {
188
+ throw new Error("Invalid selection indices");
189
+ }
190
+ return values;
191
+ }
@@ -0,0 +1,26 @@
1
+ export type SpinnerIndicator = "timer" | "dots";
2
+ export interface SpinnerOptions {
3
+ text?: string;
4
+ indicator?: SpinnerIndicator;
5
+ frames?: string[];
6
+ delay?: number;
7
+ onCancel?: () => void;
8
+ cancelMessage?: string;
9
+ errorMessage?: string;
10
+ successText?: string;
11
+ failText?: string;
12
+ prefixText?: string;
13
+ color?: string;
14
+ hideCursor?: boolean;
15
+ silent?: boolean;
16
+ signal?: AbortSignal;
17
+ }
18
+ export interface SpinnerInstance {
19
+ start(): SpinnerInstance;
20
+ stop(): SpinnerInstance;
21
+ succeed(text?: string): SpinnerInstance;
22
+ fail(text?: string): SpinnerInstance;
23
+ updateText(text: string): SpinnerInstance;
24
+ }
25
+ export declare function spinnerPrompt(options?: SpinnerOptions): SpinnerInstance;
26
+ export declare function createSpinner(options?: SpinnerOptions): SpinnerInstance;