@reliverse/rempts 1.6.0

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 (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +408 -0
  3. package/bin/core-impl/anykey/anykey-mod.d.ts +12 -0
  4. package/bin/core-impl/anykey/anykey-mod.js +125 -0
  5. package/bin/core-impl/date/date.d.ts +2 -0
  6. package/bin/core-impl/date/date.js +236 -0
  7. package/bin/core-impl/editor/editor-mod.d.ts +25 -0
  8. package/bin/core-impl/editor/editor-mod.js +897 -0
  9. package/bin/core-impl/figures/figures-mod.d.ts +462 -0
  10. package/bin/core-impl/figures/figures-mod.js +286 -0
  11. package/bin/core-impl/figures/figures.test.d.ts +1 -0
  12. package/bin/core-impl/figures/figures.test.js +474 -0
  13. package/bin/core-impl/input/confirm-prompt.d.ts +5 -0
  14. package/bin/core-impl/input/confirm-prompt.js +173 -0
  15. package/bin/core-impl/input/input-prompt.d.ts +16 -0
  16. package/bin/core-impl/input/input-prompt.js +370 -0
  17. package/bin/core-impl/launcher/deprecated/_parser.ts.txt +167 -0
  18. package/bin/core-impl/launcher/deprecated/_utils.ts.txt +41 -0
  19. package/bin/core-impl/launcher/deprecated/args.ts.txt +108 -0
  20. package/bin/core-impl/launcher/deprecated/command.ts.txt +95 -0
  21. package/bin/core-impl/launcher/deprecated/launcher-mod.ts.txt +50 -0
  22. package/bin/core-impl/launcher/deprecated/usage.ts.txt +157 -0
  23. package/bin/core-impl/launcher/launcher-mod.d.ts +87 -0
  24. package/bin/core-impl/launcher/launcher-mod.js +364 -0
  25. package/bin/core-impl/msg-fmt/colors.d.ts +30 -0
  26. package/bin/core-impl/msg-fmt/colors.js +42 -0
  27. package/bin/core-impl/msg-fmt/logger.d.ts +17 -0
  28. package/bin/core-impl/msg-fmt/logger.js +106 -0
  29. package/bin/core-impl/msg-fmt/mapping.d.ts +3 -0
  30. package/bin/core-impl/msg-fmt/mapping.js +49 -0
  31. package/bin/core-impl/msg-fmt/messages.d.ts +35 -0
  32. package/bin/core-impl/msg-fmt/messages.js +316 -0
  33. package/bin/core-impl/msg-fmt/terminal.d.ts +15 -0
  34. package/bin/core-impl/msg-fmt/terminal.js +60 -0
  35. package/bin/core-impl/msg-fmt/variants.d.ts +11 -0
  36. package/bin/core-impl/msg-fmt/variants.js +52 -0
  37. package/bin/core-impl/next-steps/next-steps.d.ts +14 -0
  38. package/bin/core-impl/next-steps/next-steps.js +24 -0
  39. package/bin/core-impl/number/number-mod.d.ts +28 -0
  40. package/bin/core-impl/number/number-mod.js +197 -0
  41. package/bin/core-impl/results/results.d.ts +7 -0
  42. package/bin/core-impl/results/results.js +27 -0
  43. package/bin/core-impl/select/multiselect-prompt.d.ts +2 -0
  44. package/bin/core-impl/select/multiselect-prompt.js +342 -0
  45. package/bin/core-impl/select/nummultiselect-prompt.d.ts +6 -0
  46. package/bin/core-impl/select/nummultiselect-prompt.js +105 -0
  47. package/bin/core-impl/select/numselect-prompt.d.ts +7 -0
  48. package/bin/core-impl/select/numselect-prompt.js +115 -0
  49. package/bin/core-impl/select/select-prompt.d.ts +33 -0
  50. package/bin/core-impl/select/select-prompt.js +303 -0
  51. package/bin/core-impl/select/toggle-prompt.d.ts +5 -0
  52. package/bin/core-impl/select/toggle-prompt.js +209 -0
  53. package/bin/core-impl/st-end/end.d.ts +2 -0
  54. package/bin/core-impl/st-end/end.js +42 -0
  55. package/bin/core-impl/st-end/start.d.ts +17 -0
  56. package/bin/core-impl/st-end/start.js +67 -0
  57. package/bin/core-impl/task/progress.d.ts +2 -0
  58. package/bin/core-impl/task/progress.js +57 -0
  59. package/bin/core-impl/task/spinner.d.ts +15 -0
  60. package/bin/core-impl/task/spinner.js +110 -0
  61. package/bin/core-impl/utils/colorize.d.ts +2 -0
  62. package/bin/core-impl/utils/colorize.js +135 -0
  63. package/bin/core-impl/utils/errors.d.ts +1 -0
  64. package/bin/core-impl/utils/errors.js +17 -0
  65. package/bin/core-impl/utils/prevent.d.ts +8 -0
  66. package/bin/core-impl/utils/prevent.js +65 -0
  67. package/bin/core-impl/utils/prompt-end.d.ts +8 -0
  68. package/bin/core-impl/utils/prompt-end.js +34 -0
  69. package/bin/core-impl/utils/stream-text.d.ts +18 -0
  70. package/bin/core-impl/utils/stream-text.js +136 -0
  71. package/bin/core-impl/utils/system.d.ts +6 -0
  72. package/bin/core-impl/utils/system.js +7 -0
  73. package/bin/core-impl/utils/validate.d.ts +21 -0
  74. package/bin/core-impl/utils/validate.js +17 -0
  75. package/bin/core-impl/visual/animate/animate.d.ts +14 -0
  76. package/bin/core-impl/visual/animate/animate.js +65 -0
  77. package/bin/core-impl/visual/ascii-art/ascii-art.d.ts +6 -0
  78. package/bin/core-impl/visual/ascii-art/ascii-art.js +13 -0
  79. package/bin/core-types.d.ts +334 -0
  80. package/bin/core-types.js +0 -0
  81. package/bin/main.d.ts +36 -0
  82. package/bin/main.js +86 -0
  83. package/package.json +58 -0
@@ -0,0 +1,95 @@
1
+ import type {
2
+ ArgsDef,
3
+ CommandContext,
4
+ CommandDef,
5
+ RunCommandOptions,
6
+ } from "~/libs/core/core-types.js";
7
+
8
+ import { CLIError, resolveValue } from "./_utils.js";
9
+ import { parseArgs } from "./args.js";
10
+
11
+ export function defineCommand<const T extends ArgsDef = ArgsDef>(
12
+ def: CommandDef<T>,
13
+ ): CommandDef<T> {
14
+ return def;
15
+ }
16
+
17
+ export async function runCommand<T extends ArgsDef = ArgsDef>(
18
+ cmd: CommandDef<T>,
19
+ opts: RunCommandOptions,
20
+ ): Promise<{ result: unknown }> {
21
+ const cmdArgs = await resolveValue(cmd.args || {});
22
+ const parsedArgs = parseArgs<T>(opts.rawArgs, cmdArgs);
23
+
24
+ const context: CommandContext<T> = {
25
+ rawArgs: opts.rawArgs,
26
+ args: parsedArgs,
27
+ data: opts.data,
28
+ cmd,
29
+ };
30
+
31
+ // Setup hook
32
+ if (typeof cmd.setup === "function") {
33
+ await cmd.setup(context);
34
+ }
35
+
36
+ // Handle sub command
37
+ let result: unknown;
38
+ try {
39
+ const subCommands = await resolveValue(cmd.subCommands);
40
+ if (subCommands && Object.keys(subCommands).length > 0) {
41
+ const subCommandArgIndex = opts.rawArgs.findIndex(
42
+ (arg) => !arg.startsWith("-"),
43
+ );
44
+ const subCommandName = opts.rawArgs[subCommandArgIndex];
45
+ if (subCommandName) {
46
+ if (!subCommands[subCommandName]) {
47
+ throw new CLIError(
48
+ `Unknown command \`${subCommandName}\``,
49
+ "E_UNKNOWN_COMMAND",
50
+ );
51
+ }
52
+ const subCommand = await resolveValue(subCommands[subCommandName]);
53
+ if (subCommand) {
54
+ await runCommand(subCommand, {
55
+ rawArgs: opts.rawArgs.slice(subCommandArgIndex + 1),
56
+ });
57
+ }
58
+ } else if (!cmd.run) {
59
+ // biome-ignore lint/style/noUnusedTemplateLiteral: <explanation>
60
+ throw new CLIError(`No command specified.`, "E_NO_COMMAND");
61
+ }
62
+ }
63
+
64
+ // Handle main command
65
+ if (typeof cmd.run === "function") {
66
+ result = await cmd.run(context);
67
+ }
68
+ } finally {
69
+ if (typeof cmd.cleanup === "function") {
70
+ await cmd.cleanup(context);
71
+ }
72
+ }
73
+ return { result };
74
+ }
75
+
76
+ export async function resolveSubCommand<T extends ArgsDef = ArgsDef>(
77
+ cmd: CommandDef<T>,
78
+ rawArgs: string[],
79
+ parent?: CommandDef<T>,
80
+ ): Promise<[CommandDef<T>, CommandDef<T>?]> {
81
+ const subCommands = await resolveValue(cmd.subCommands);
82
+ if (subCommands && Object.keys(subCommands).length > 0) {
83
+ const subCommandArgIndex = rawArgs.findIndex((arg) => !arg.startsWith("-"));
84
+ const subCommandName = rawArgs[subCommandArgIndex];
85
+ const subCommand = await resolveValue(subCommands[subCommandName]);
86
+ if (subCommand) {
87
+ return resolveSubCommand(
88
+ subCommand,
89
+ rawArgs.slice(subCommandArgIndex + 1),
90
+ cmd,
91
+ );
92
+ }
93
+ }
94
+ return [cmd, parent];
95
+ }
@@ -0,0 +1,50 @@
1
+ import { relinka } from "@reliverse/relinka";
2
+
3
+ import type { ArgsDef, CommandDef } from "~/libs/core/core-types.js";
4
+
5
+ import { CLIError } from "./_utils.js";
6
+ import { resolveSubCommand, runCommand } from "./command.js";
7
+ import { showUsage as _showUsage } from "./usage.js";
8
+
9
+ export type RunMainOptions = {
10
+ rawArgs?: string[];
11
+ showUsage?: typeof _showUsage;
12
+ };
13
+
14
+ export async function runMain<T extends ArgsDef = ArgsDef>(
15
+ cmd: CommandDef<T>,
16
+ opts: RunMainOptions = {},
17
+ ) {
18
+ const rawArgs = opts.rawArgs || process.argv.slice(2);
19
+ const showUsage = opts.showUsage || _showUsage;
20
+ try {
21
+ if (rawArgs.includes("--help") || rawArgs.includes("-h")) {
22
+ await showUsage(...(await resolveSubCommand(cmd, rawArgs)));
23
+ process.exit(0);
24
+ } else if (rawArgs.length === 1 && rawArgs[0] === "--version") {
25
+ const meta =
26
+ typeof cmd.meta === "function" ? await cmd.meta() : await cmd.meta;
27
+ if (!meta?.version) {
28
+ throw new CLIError("No version specified", "E_NO_VERSION");
29
+ }
30
+ relinka("info", meta.version);
31
+ } else {
32
+ await runCommand(cmd, { rawArgs });
33
+ }
34
+ } catch (error: any) {
35
+ const isCLIError = error instanceof CLIError;
36
+ if (isCLIError) {
37
+ await showUsage(...(await resolveSubCommand(cmd, rawArgs)));
38
+ relinka("error", error.message);
39
+ } else {
40
+ relinka("error", error, "\n");
41
+ }
42
+ process.exit(1);
43
+ }
44
+ }
45
+
46
+ export function createMain<T extends ArgsDef = ArgsDef>(
47
+ cmd: CommandDef<T>,
48
+ ): (opts?: RunMainOptions) => Promise<void> {
49
+ return (opts: RunMainOptions = {}) => runMain(cmd, opts);
50
+ }
@@ -0,0 +1,157 @@
1
+ import { re } from "@reliverse/relico";
2
+ import { relinka } from "@reliverse/relinka";
3
+
4
+ import type { ArgsDef, CommandDef } from "~/libs/core/core-types.js";
5
+
6
+ import { formatLineColumns, resolveValue } from "./_utils.js";
7
+ import { resolveArgs } from "./args.js";
8
+
9
+ export async function showUsage<T extends ArgsDef = ArgsDef>(
10
+ cmd: CommandDef<T>,
11
+ parent?: CommandDef<T>,
12
+ ) {
13
+ try {
14
+ // biome-ignore lint/style/useTemplate: <explanation>
15
+ relinka("info", (await renderUsage(cmd, parent)) + "\n");
16
+ } catch (error) {
17
+ relinka("error", String(error));
18
+ }
19
+ }
20
+
21
+ // `no` prefix matcher (kebab-case or camelCase)
22
+ const negativePrefixRe = /^no[-A-Z]/;
23
+
24
+ export async function renderUsage<T extends ArgsDef = ArgsDef>(
25
+ cmd: CommandDef<T>,
26
+ parent?: CommandDef<T>,
27
+ ) {
28
+ const cmdMeta = await resolveValue(cmd.meta || {});
29
+ const cmdArgs = resolveArgs(await resolveValue(cmd.args || {}));
30
+ const parentMeta = await resolveValue(parent?.meta || {});
31
+
32
+ const commandName =
33
+ (parentMeta.name ? `${parentMeta.name} ` : "") +
34
+ (cmdMeta.name || process.argv[1]);
35
+
36
+ const argLines: string[][] = [];
37
+ const posLines: string[][] = [];
38
+ const commandsLines: string[][] = [];
39
+ const usageLine = [];
40
+
41
+ for (const arg of cmdArgs) {
42
+ if (arg.type === "positional") {
43
+ const name = arg.name.toUpperCase();
44
+ const isRequired = arg.required !== false && arg.default === undefined;
45
+ // (isRequired ? " (required)" : " (optional)"
46
+ const defaultHint = arg.default ? `="${arg.default}"` : "";
47
+ posLines.push([
48
+ // biome-ignore lint/style/useTemplate: <explanation>
49
+ "`" + name + defaultHint + "`",
50
+ arg.description || "",
51
+ arg.valueHint ? `<${arg.valueHint}>` : "",
52
+ ]);
53
+ usageLine.push(isRequired ? `<${name}>` : `[${name}]`);
54
+ } else {
55
+ const isRequired = arg.required === true && arg.default === undefined;
56
+ const argStr =
57
+ [...(arg.alias || []).map((a) => `-${a}`), `--${arg.name}`].join(", ") +
58
+ (arg.type === "string" && (arg.valueHint || arg.default)
59
+ ? `=${
60
+ arg.valueHint ? `<${arg.valueHint}>` : `"${arg.default || ""}"`
61
+ }`
62
+ : "") +
63
+ (arg.type === "enum" && arg.options
64
+ ? `=<${arg.options.join("|")}>`
65
+ : "");
66
+ argLines.push([
67
+ // biome-ignore lint/style/useTemplate: <explanation>
68
+ "`" + argStr + (isRequired ? " (required)" : "") + "`",
69
+ arg.description || "",
70
+ ]);
71
+
72
+ /**
73
+ * print negative boolean arg variant usage when
74
+ * - enabled by default or has `negativeDescription`
75
+ * - not prefixed with `no-` or `no[A-Z]`
76
+ */
77
+ if (
78
+ arg.type === "boolean" &&
79
+ (arg.default === true || arg.negativeDescription) &&
80
+ !negativePrefixRe.test(arg.name)
81
+ ) {
82
+ const negativeArgStr = [
83
+ ...(arg.alias || []).map((a) => `--no-${a}`),
84
+ `--no-${arg.name}`,
85
+ ].join(", ");
86
+ argLines.push([
87
+ // biome-ignore lint/style/useTemplate: <explanation>
88
+ "`" + negativeArgStr + (isRequired ? " (required)" : "") + "`",
89
+ arg.negativeDescription || "",
90
+ ]);
91
+ }
92
+
93
+ if (isRequired) {
94
+ usageLine.push(argStr);
95
+ }
96
+ }
97
+ }
98
+
99
+ if (cmd.subCommands) {
100
+ const commandNames: string[] = [];
101
+ const subCommands = await resolveValue(cmd.subCommands);
102
+ for (const [name, sub] of Object.entries(subCommands)) {
103
+ const subCmd = await resolveValue(sub);
104
+ const meta = await resolveValue(subCmd?.meta);
105
+ if (meta?.hidden) {
106
+ continue;
107
+ }
108
+ commandsLines.push([`\`${name}\``, meta?.description || ""]);
109
+ commandNames.push(name);
110
+ }
111
+ usageLine.push(commandNames.join("|"));
112
+ }
113
+
114
+ const usageLines: (string | undefined)[] = [];
115
+
116
+ const version = cmdMeta.version || parentMeta.version;
117
+
118
+ usageLines.push(
119
+ re.gray(
120
+ `${cmdMeta.description} (${
121
+ commandName + (version ? ` v${version}` : "")
122
+ })`,
123
+ ),
124
+ "",
125
+ );
126
+
127
+ const hasOptions = argLines.length > 0 || posLines.length > 0;
128
+ usageLines.push(
129
+ `${re.underline(re.bold("USAGE"))} \`${commandName}${
130
+ hasOptions ? " [OPTIONS]" : ""
131
+ } ${usageLine.join(" ")}\``,
132
+ "",
133
+ );
134
+
135
+ if (posLines.length > 0) {
136
+ usageLines.push(re.underline(re.bold("ARGUMENTS")), "");
137
+ usageLines.push(formatLineColumns(posLines, " "));
138
+ usageLines.push("");
139
+ }
140
+
141
+ if (argLines.length > 0) {
142
+ usageLines.push(re.underline(re.bold("OPTIONS")), "");
143
+ usageLines.push(formatLineColumns(argLines, " "));
144
+ usageLines.push("");
145
+ }
146
+
147
+ if (commandsLines.length > 0) {
148
+ usageLines.push(re.underline(re.bold("COMMANDS")), "");
149
+ usageLines.push(formatLineColumns(commandsLines, " "));
150
+ usageLines.push(
151
+ "",
152
+ `Use \`${commandName} <command> --help\` for more information about a command.`,
153
+ );
154
+ }
155
+
156
+ return usageLines.filter((l) => typeof l === "string").join("\n");
157
+ }
@@ -0,0 +1,87 @@
1
+ import type { ReliArgParserOptions } from "@reliverse/reliarg";
2
+ type EmptyArgs = Record<string, never>;
3
+ type BaseArgDefinition = {
4
+ description?: string;
5
+ required?: boolean;
6
+ default?: any;
7
+ };
8
+ type PositionalArgDefinition = {
9
+ type: "positional";
10
+ } & BaseArgDefinition;
11
+ type BooleanArgDefinition = {
12
+ type: "boolean";
13
+ } & BaseArgDefinition;
14
+ type StringArgDefinition = {
15
+ type: "string";
16
+ } & BaseArgDefinition;
17
+ type NumberArgDefinition = {
18
+ type: "number";
19
+ } & BaseArgDefinition;
20
+ type ArrayArgDefinition = {
21
+ type: "array";
22
+ } & BaseArgDefinition;
23
+ export type ArgDefinition = PositionalArgDefinition | BooleanArgDefinition | StringArgDefinition | NumberArgDefinition | ArrayArgDefinition;
24
+ export type ArgDefinitions = Record<string, ArgDefinition>;
25
+ type CommandMeta = {
26
+ name: string;
27
+ version?: string;
28
+ description?: string;
29
+ hidden?: boolean;
30
+ aliases?: string[];
31
+ };
32
+ /**
33
+ * A subcommand can be either:
34
+ * 1) A string path to a module with a default export of type Command.
35
+ * 2) A lazy import function returning a Promise that resolves to { default: Command<any> } or directly to a Command instance.
36
+ */
37
+ type SubCommandSpec = string | (() => Promise<{
38
+ default: Command<any>;
39
+ } | Command<any>>);
40
+ export type SubCommandsMap = Record<string, SubCommandSpec>;
41
+ type CommandContext<ARGS> = {
42
+ args: ARGS;
43
+ raw: string[];
44
+ };
45
+ type CommandRun<ARGS> = (ctx: CommandContext<ARGS>) => void | Promise<void>;
46
+ type DefineCommandOptions<A extends ArgDefinitions = EmptyArgs> = {
47
+ meta: CommandMeta;
48
+ args?: A;
49
+ run: CommandRun<InferArgTypes<A>>;
50
+ subCommands?: SubCommandsMap;
51
+ };
52
+ export type Command<A extends ArgDefinitions = EmptyArgs> = {
53
+ meta: CommandMeta;
54
+ args: A;
55
+ run: CommandRun<InferArgTypes<A>>;
56
+ subCommands?: SubCommandsMap;
57
+ };
58
+ export type InferArgTypes<A extends ArgDefinitions> = {
59
+ [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 ArrayArgDefinition ? string[] : never;
60
+ };
61
+ export type FileBasedCmdsOptions = {
62
+ enable: boolean;
63
+ cmdsRootPath: string;
64
+ };
65
+ /**
66
+ * Defines a command with metadata, argument definitions,
67
+ * an execution function, and subCommands.
68
+ */
69
+ export declare function defineCommand<A extends ArgDefinitions = EmptyArgs>(options: DefineCommandOptions<A>): Command<A>;
70
+ /**
71
+ * Show usage for a given command.
72
+ */
73
+ export declare function showUsage<A extends ArgDefinitions>(command: Command<A>, parserOptions?: ReliArgParserOptions & {
74
+ fileBasedCmds?: FileBasedCmdsOptions;
75
+ autoExit?: boolean;
76
+ }): Promise<void>;
77
+ /**
78
+ * Primary entry point to run a command, with support for subcommands or file-based commands.
79
+ *
80
+ * If the user does not provide any subCommands (or they are empty) AND no fileBasedCmds options,
81
+ * then file-based command detection is automatically enabled with a default cmdsRootPath.
82
+ */
83
+ export declare function runMain<A extends ArgDefinitions = EmptyArgs>(command: Command<A>, parserOptions?: ReliArgParserOptions & {
84
+ fileBasedCmds?: FileBasedCmdsOptions;
85
+ autoExit?: boolean;
86
+ }): Promise<void>;
87
+ export {};