@reliverse/rempts 1.7.29 → 1.7.31
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 +141 -29
- package/bin/{components/animate/animate.js → libs/animate/animate-mod.js} +1 -4
- package/bin/{components → libs}/anykey/anykey-mod.js +2 -2
- package/bin/libs/confirm/confirm-alias.d.ts +1 -0
- package/bin/libs/confirm/confirm-alias.js +2 -0
- package/bin/{components/confirm/confirm-prompt.js → libs/confirm/confirm-mod.js} +1 -1
- package/bin/{components → libs}/editor/editor-mod.js +8 -8
- package/bin/{components → libs}/figures/figures-mod.d.ts +2 -3
- package/bin/{components → libs}/figures/figures-mod.js +1 -2
- package/bin/libs/input/input-alias.d.ts +4 -0
- package/bin/libs/input/input-alias.js +4 -0
- package/bin/{components/input/input-prompt.js → libs/input/input-mod.js} +2 -2
- package/bin/libs/intro/intro-alias.d.ts +2 -0
- package/bin/libs/intro/intro-alias.js +3 -0
- package/bin/{components/intro/intro-start.js → libs/intro/intro-mod.js} +3 -3
- package/bin/libs/launcher/launcher-alias.d.ts +2 -0
- package/bin/libs/launcher/launcher-alias.js +2 -0
- package/bin/libs/launcher/launcher-mod.d.ts +114 -0
- package/bin/{components → libs}/launcher/launcher-mod.js +355 -191
- package/bin/{components → libs}/launcher/launcher-types.d.ts +1 -1
- package/bin/libs/launcher/trpc-orpc-support/completions.d.ts +4 -0
- package/bin/libs/launcher/trpc-orpc-support/completions.js +45 -0
- package/bin/libs/launcher/trpc-orpc-support/errors.d.ts +11 -0
- package/bin/libs/launcher/trpc-orpc-support/errors.js +10 -0
- package/bin/libs/launcher/trpc-orpc-support/index.d.ts +34 -0
- package/bin/libs/launcher/trpc-orpc-support/index.js +641 -0
- package/bin/libs/launcher/trpc-orpc-support/json-schema.d.ts +17 -0
- package/bin/libs/launcher/trpc-orpc-support/json-schema.js +168 -0
- package/bin/libs/launcher/trpc-orpc-support/json.d.ts +44 -0
- package/bin/libs/launcher/trpc-orpc-support/json.js +41 -0
- package/bin/libs/launcher/trpc-orpc-support/logging.d.ts +11 -0
- package/bin/libs/launcher/trpc-orpc-support/logging.js +26 -0
- package/bin/libs/launcher/trpc-orpc-support/parse-procedure.d.ts +2 -0
- package/bin/libs/launcher/trpc-orpc-support/parse-procedure.js +486 -0
- package/bin/libs/launcher/trpc-orpc-support/prompts.d.ts +18 -0
- package/bin/libs/launcher/trpc-orpc-support/prompts.js +534 -0
- package/bin/libs/launcher/trpc-orpc-support/standard-schema/contract.d.ts +53 -0
- package/bin/libs/launcher/trpc-orpc-support/standard-schema/contract.js +0 -0
- package/bin/libs/launcher/trpc-orpc-support/standard-schema/errors.d.ts +9 -0
- package/bin/libs/launcher/trpc-orpc-support/standard-schema/errors.js +47 -0
- package/bin/libs/launcher/trpc-orpc-support/standard-schema/utils.d.ts +3 -0
- package/bin/libs/launcher/trpc-orpc-support/standard-schema/utils.js +6 -0
- package/bin/libs/launcher/trpc-orpc-support/trpc-compat.d.ts +71 -0
- package/bin/libs/launcher/trpc-orpc-support/trpc-compat.js +11 -0
- package/bin/libs/launcher/trpc-orpc-support/types.d.ts +276 -0
- package/bin/libs/launcher/trpc-orpc-support/types.js +0 -0
- package/bin/libs/launcher/trpc-orpc-support/util.d.ts +9 -0
- package/bin/libs/launcher/trpc-orpc-support/util.js +9 -0
- package/bin/{components → libs}/msg-fmt/logger.js +1 -1
- package/bin/libs/multiselect/multiselect-alias.d.ts +1 -0
- package/bin/libs/multiselect/multiselect-alias.js +2 -0
- package/bin/{components/select → libs/multiselect}/multiselect-prompt.js +1 -1
- package/bin/{components → libs}/number/number-mod.js +1 -4
- package/bin/libs/outro/outro-alias.d.ts +2 -0
- package/bin/libs/outro/outro-alias.js +3 -0
- package/bin/{components/outro/outro-end.js → libs/outro/outro-mod.js} +2 -2
- package/bin/libs/select/aliases-alias.d.ts +1 -0
- package/bin/libs/select/aliases-alias.js +2 -0
- package/bin/{components → libs}/select/select-prompt.js +2 -2
- package/bin/{components → libs}/select/toggle-prompt.js +1 -1
- package/bin/libs/spinner/spinner-alias.d.ts +1 -0
- package/bin/libs/spinner/spinner-alias.js +2 -0
- package/bin/{components → libs}/spinner/spinner-mod.js +3 -1
- package/bin/{components → libs}/task/task-spin.js +1 -1
- package/bin/{utils → libs/utils}/colorize.d.ts +1 -1
- package/bin/{utils → libs/utils}/prevent.d.ts +1 -1
- package/bin/{utils → libs/utils}/prevent.js +2 -2
- package/bin/{utils → libs/utils}/prompt-end.d.ts +1 -1
- package/bin/{utils → libs/utils}/prompt-end.js +2 -2
- package/bin/{utils → libs/utils}/stream-text.d.ts +1 -1
- package/bin/{utils → libs/utils}/stream-text.js +2 -2
- package/bin/mod.d.ts +66 -41
- package/bin/mod.js +102 -66
- package/package.json +17 -2
- package/bin/components/aliases/aliases-mod.d.ts +0 -11
- package/bin/components/aliases/aliases-mod.js +0 -16
- package/bin/components/launcher/launcher-mod.d.ts +0 -52
- /package/bin/{components/animate/animate.d.ts → libs/animate/animate-mod.d.ts} +0 -0
- /package/bin/{components → libs}/anykey/anykey-mod.d.ts +0 -0
- /package/bin/{components → libs}/cancel/cancel.d.ts +0 -0
- /package/bin/{components → libs}/cancel/cancel.js +0 -0
- /package/bin/{components/confirm/confirm-prompt.d.ts → libs/confirm/confirm-mod.d.ts} +0 -0
- /package/bin/{components → libs}/date/date.d.ts +0 -0
- /package/bin/{components → libs}/date/date.js +0 -0
- /package/bin/{components → libs}/editor/editor-mod.d.ts +0 -0
- /package/bin/{components/input/input-prompt.d.ts → libs/input/input-mod.d.ts} +0 -0
- /package/bin/{components/intro/intro-start.d.ts → libs/intro/intro-mod.d.ts} +0 -0
- /package/bin/{components → libs}/launcher/launcher-types.js +0 -0
- /package/bin/{components → libs}/launcher/run-command.d.ts +0 -0
- /package/bin/{components → libs}/launcher/run-command.js +0 -0
- /package/bin/{components/log/log.d.ts → libs/log/log-alias.d.ts} +0 -0
- /package/bin/{components/log/log.js → libs/log/log-alias.js} +0 -0
- /package/bin/{components → libs}/msg-fmt/colors.d.ts +0 -0
- /package/bin/{components → libs}/msg-fmt/colors.js +0 -0
- /package/bin/{components → libs}/msg-fmt/logger.d.ts +0 -0
- /package/bin/{components → libs}/msg-fmt/mapping.d.ts +0 -0
- /package/bin/{components → libs}/msg-fmt/mapping.js +0 -0
- /package/bin/{components → libs}/msg-fmt/messages.d.ts +0 -0
- /package/bin/{components → libs}/msg-fmt/messages.js +0 -0
- /package/bin/{components → libs}/msg-fmt/terminal.d.ts +0 -0
- /package/bin/{components → libs}/msg-fmt/terminal.js +0 -0
- /package/bin/{components → libs}/msg-fmt/variants.d.ts +0 -0
- /package/bin/{components → libs}/msg-fmt/variants.js +0 -0
- /package/bin/{components/select → libs/multiselect}/multiselect-prompt.d.ts +0 -0
- /package/bin/{components → libs}/next-steps/next-steps.d.ts +0 -0
- /package/bin/{components → libs}/next-steps/next-steps.js +0 -0
- /package/bin/{components → libs}/number/number-mod.d.ts +0 -0
- /package/bin/{components/outro/outro-end.d.ts → libs/outro/outro-mod.d.ts} +0 -0
- /package/bin/{components → libs}/results/results.d.ts +0 -0
- /package/bin/{components → libs}/results/results.js +0 -0
- /package/bin/{components → libs}/select/nummultiselect-prompt.d.ts +0 -0
- /package/bin/{components → libs}/select/nummultiselect-prompt.js +0 -0
- /package/bin/{components → libs}/select/numselect-prompt.d.ts +0 -0
- /package/bin/{components → libs}/select/numselect-prompt.js +0 -0
- /package/bin/{components → libs}/select/select-prompt.d.ts +0 -0
- /package/bin/{components → libs}/select/toggle-prompt.d.ts +0 -0
- /package/bin/{components → libs}/spinner/spinner-mod.d.ts +0 -0
- /package/bin/{components → libs}/task/progress.d.ts +0 -0
- /package/bin/{components → libs}/task/progress.js +0 -0
- /package/bin/{components → libs}/task/task-spin.d.ts +0 -0
- /package/bin/{utils → libs/utils}/colorize.js +0 -0
- /package/bin/{utils → libs/utils}/errors.d.ts +0 -0
- /package/bin/{utils → libs/utils}/errors.js +0 -0
- /package/bin/{utils → libs/utils}/system.d.ts +0 -0
- /package/bin/{utils → libs/utils}/system.js +0 -0
- /package/bin/{utils → libs/utils}/validate.d.ts +0 -0
- /package/bin/{utils → libs/utils}/validate.js +0 -0
- /package/bin/{components/ascii-art/ascii-art.d.ts → libs/visual/visual-mod.d.ts} +0 -0
- /package/bin/{components/ascii-art/ascii-art.js → libs/visual/visual-mod.js} +0 -0
package/README.md
CHANGED
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
- 🏞️ no more hacking together `inquirer`/`citty`/`commander`/`chalk`
|
|
29
29
|
- 🆕 automatic command creation (`bun dler rempts --init cmd1 cmd2`)
|
|
30
30
|
- 🐦🔥 automatic creation of `src/app/cmds.ts` file (`bun dler rempts`)
|
|
31
|
+
- 🔌 tRPC/ORPC router integration - automatically generate CLI commands from your RPC procedures
|
|
31
32
|
|
|
32
33
|
## Installation
|
|
33
34
|
|
|
@@ -59,14 +60,13 @@ All main prompts APIs are available from the package root:
|
|
|
59
60
|
```ts
|
|
60
61
|
import {
|
|
61
62
|
// ...prompts
|
|
62
|
-
defineCommand, runMain, defineArgs,
|
|
63
63
|
inputPrompt, selectPrompt, multiselectPrompt, numberPrompt,
|
|
64
64
|
confirmPrompt, togglePrompt, taskSpinPrompt, taskProgressPrompt,
|
|
65
65
|
startPrompt, endPrompt, resultPrompt, nextStepsPrompt,
|
|
66
66
|
// ...hooks
|
|
67
67
|
useSpinner,
|
|
68
68
|
// ...launcher
|
|
69
|
-
|
|
69
|
+
createCli, defineCommand, defineArgs,
|
|
70
70
|
// ...types
|
|
71
71
|
// ...more
|
|
72
72
|
} from "@reliverse/rempts";
|
|
@@ -218,6 +218,8 @@ await main();
|
|
|
218
218
|
|
|
219
219
|
## Launcher
|
|
220
220
|
|
|
221
|
+
> **Note**: `runMain` is now an alias for `createCli` and is still supported for backward compatibility. The new `createCli` API provides a more intuitive object-based configuration format.
|
|
222
|
+
|
|
221
223
|
### Terminology
|
|
222
224
|
|
|
223
225
|
- **Launcher/Router**: The main entry point for your CLI. Visit [CLI Launcher (Router)](#cli-launcher-router) section to learn more.
|
|
@@ -228,12 +230,12 @@ await main();
|
|
|
228
230
|
|
|
229
231
|
#### Launcher Usage Example
|
|
230
232
|
|
|
231
|
-
**Important**: Ensure your commands don't have `await main();`, `await
|
|
233
|
+
**Important**: Ensure your commands don't have `await main();`, `await createCli();`, or something like that — to prevent any unexpected behavior. Only main command should have it.
|
|
232
234
|
|
|
233
235
|
```ts
|
|
234
236
|
import { relinka } from "@reliverse/relinka";
|
|
235
237
|
|
|
236
|
-
import { defineCommand,
|
|
238
|
+
import { defineCommand, createCli } from "@reliverse/rempts";
|
|
237
239
|
|
|
238
240
|
const main = defineCommand({
|
|
239
241
|
meta: {
|
|
@@ -254,12 +256,20 @@ const main = defineCommand({
|
|
|
254
256
|
},
|
|
255
257
|
});
|
|
256
258
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
+
// New object format (recommended)
|
|
260
|
+
await createCli({
|
|
261
|
+
mainCommand: main,
|
|
262
|
+
fileBased: {
|
|
263
|
+
enable: true,
|
|
264
|
+
cmdsRootPath: "my-cmds", // default is `./app`
|
|
265
|
+
},
|
|
266
|
+
// Optionally disable auto-exit to handle errors manually:
|
|
267
|
+
autoExit: false,
|
|
268
|
+
});
|
|
259
269
|
|
|
260
|
-
|
|
261
|
-
await
|
|
262
|
-
|
|
270
|
+
// Legacy format (still supported)
|
|
271
|
+
await createCli(main, {
|
|
272
|
+
fileBased: {
|
|
263
273
|
enable: true,
|
|
264
274
|
cmdsRootPath: "my-cmds", // default is `./app`
|
|
265
275
|
},
|
|
@@ -355,6 +365,48 @@ See [example/launcher/app/nested](./example/launcher/app/nested/) and [example/l
|
|
|
355
365
|
|
|
356
366
|
When playing with the example, you can run e.g. `bun dev:modern nested foo bar baz` to see the result in action.
|
|
357
367
|
|
|
368
|
+
## RPC Integration
|
|
369
|
+
|
|
370
|
+
Rempts now supports seamless integration with tRPC and ORPC routers, allowing you to automatically generate CLI commands from your RPC procedures. This provides a powerful way to expose your API endpoints as command-line tools.
|
|
371
|
+
|
|
372
|
+
```typescript
|
|
373
|
+
import { z } from "zod";
|
|
374
|
+
import { initTRPC } from "@trpc/server";
|
|
375
|
+
import { createCli } from "@reliverse/rempts";
|
|
376
|
+
|
|
377
|
+
const t = initTRPC.create();
|
|
378
|
+
|
|
379
|
+
const appRouter = t.router({
|
|
380
|
+
hello: t.procedure
|
|
381
|
+
.input(z.object({ name: z.string().optional() }))
|
|
382
|
+
.query(({ input }) => `Hello ${input.name ?? "World"}!`),
|
|
383
|
+
|
|
384
|
+
add: t.procedure
|
|
385
|
+
.input(z.object({ a: z.number(), b: z.number() }))
|
|
386
|
+
.mutation(({ input }) => input.a + input.b)
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
// Automatically generates CLI commands from your tRPC procedures
|
|
390
|
+
await createCli({
|
|
391
|
+
name: "my-cli",
|
|
392
|
+
rpc: { router: appRouter }
|
|
393
|
+
});
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
**Features:**
|
|
397
|
+
|
|
398
|
+
- 🚀 Automatic CLI generation from tRPC procedures
|
|
399
|
+
- 🔄 Support for both tRPC v10 and v11
|
|
400
|
+
- 🏗️ Nested command structures from sub-routers
|
|
401
|
+
- ✅ Input validation from Zod schemas
|
|
402
|
+
- 📖 Automatic help generation from procedure metadata
|
|
403
|
+
- 🎯 Full TypeScript support with type inference
|
|
404
|
+
- 🎨 Interactive prompts for missing arguments
|
|
405
|
+
- ⌨️ Shell completion support
|
|
406
|
+
- 🔧 Customizable logging and error handling
|
|
407
|
+
|
|
408
|
+
See [RPC Integration Guide](./docs/launcher-rpc.md) for detailed documentation and examples.
|
|
409
|
+
|
|
358
410
|
### Playground
|
|
359
411
|
|
|
360
412
|
```bash
|
|
@@ -368,6 +420,12 @@ bun dev
|
|
|
368
420
|
- `bun dev:modern`: This example will show you a modern CLI launcher usage with file-based commands.
|
|
369
421
|
- `bun dev:classic`: This example will show you a classic CLI launcher usage with programmatic commands.
|
|
370
422
|
|
|
423
|
+
### tRPC/oRPC Integration Example Commands
|
|
424
|
+
|
|
425
|
+
```bash
|
|
426
|
+
bun example/trpc-orpc/rempts/effect-primary.ts create-profile --name 'Jane Smith' --age 28 --bio 'Software Engineer' --tags 'developer,typescript'
|
|
427
|
+
```
|
|
428
|
+
|
|
371
429
|
### Launcher Usage Examples
|
|
372
430
|
|
|
373
431
|
#### Minimal Usage Example
|
|
@@ -375,9 +433,15 @@ bun dev
|
|
|
375
433
|
**1 Create a `src/mod.ts` file:**
|
|
376
434
|
|
|
377
435
|
```ts
|
|
378
|
-
import {
|
|
436
|
+
import { createCli, defineCommand } from "@reliverse/rempts";
|
|
437
|
+
|
|
438
|
+
// New object format (recommended)
|
|
439
|
+
await createCli({
|
|
440
|
+
mainCommand: defineCommand({}),
|
|
441
|
+
});
|
|
379
442
|
|
|
380
|
-
|
|
443
|
+
// Legacy format (still supported)
|
|
444
|
+
await createCli(defineCommand({}));
|
|
381
445
|
```
|
|
382
446
|
|
|
383
447
|
**2 Run the following:**
|
|
@@ -406,7 +470,7 @@ bun src/mod.ts
|
|
|
406
470
|
#### Medium Usage Example
|
|
407
471
|
|
|
408
472
|
```ts
|
|
409
|
-
import { defineCommand,
|
|
473
|
+
import { defineCommand, createCli } from "@reliverse/rempts";
|
|
410
474
|
|
|
411
475
|
const main = defineCommand({
|
|
412
476
|
meta: {
|
|
@@ -417,7 +481,13 @@ const main = defineCommand({
|
|
|
417
481
|
},
|
|
418
482
|
});
|
|
419
483
|
|
|
420
|
-
|
|
484
|
+
// New object format (recommended)
|
|
485
|
+
await createCli({
|
|
486
|
+
mainCommand: main,
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
// Legacy format (still supported)
|
|
490
|
+
await createCli(main);
|
|
421
491
|
```
|
|
422
492
|
|
|
423
493
|
#### Classic Usage Example
|
|
@@ -430,7 +500,7 @@ import {
|
|
|
430
500
|
inputPrompt,
|
|
431
501
|
selectPrompt,
|
|
432
502
|
defineCommand,
|
|
433
|
-
|
|
503
|
+
createCli
|
|
434
504
|
} from "@reliverse/rempts";
|
|
435
505
|
|
|
436
506
|
const main = defineCommand({
|
|
@@ -469,7 +539,13 @@ const main = defineCommand({
|
|
|
469
539
|
},
|
|
470
540
|
});
|
|
471
541
|
|
|
472
|
-
|
|
542
|
+
// New object format (recommended)
|
|
543
|
+
await createCli({
|
|
544
|
+
mainCommand: main,
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
// Legacy format (still supported)
|
|
548
|
+
await createCli(main);
|
|
473
549
|
```
|
|
474
550
|
|
|
475
551
|
#### Advanced Usage Example
|
|
@@ -584,7 +660,7 @@ const mainCommand = defineCommand({
|
|
|
584
660
|
});
|
|
585
661
|
|
|
586
662
|
/**
|
|
587
|
-
* The `
|
|
663
|
+
* The `createCli()` function sets up the launcher with several advanced features:
|
|
588
664
|
*
|
|
589
665
|
* - File-Based Commands: Enables scanning for commands within the "app" directory.
|
|
590
666
|
* - Alias Mapping: Shorthand flags (e.g., `-v`) are mapped to their full names (e.g., `--verbose`).
|
|
@@ -592,8 +668,28 @@ const mainCommand = defineCommand({
|
|
|
592
668
|
* - Negated Boolean Support: Allows flags to be negated (e.g., `--no-verbose`).
|
|
593
669
|
* - Custom Unknown Flag Handler: Provides custom handling for unrecognized flags.
|
|
594
670
|
*/
|
|
595
|
-
|
|
596
|
-
|
|
671
|
+
// New object format (recommended)
|
|
672
|
+
await createCli({
|
|
673
|
+
mainCommand: mainCommand,
|
|
674
|
+
fileBased: {
|
|
675
|
+
enable: true, // Enables file-based command detection.
|
|
676
|
+
cmdsRootPath: "app", // Directory to scan for commands.
|
|
677
|
+
},
|
|
678
|
+
alias: {
|
|
679
|
+
v: "verbose", // Maps shorthand flag -v to --verbose.
|
|
680
|
+
},
|
|
681
|
+
strict: false, // Do not throw errors for unknown flags.
|
|
682
|
+
warnOnUnknown: false, // Warn when encountering unknown flags.
|
|
683
|
+
negatedBoolean: true, // Support for negated booleans (e.g., --no-verbose).
|
|
684
|
+
// unknown: (flagName) => {
|
|
685
|
+
// relinka("warn", "Unknown flag encountered:", flagName);
|
|
686
|
+
// return false;
|
|
687
|
+
// },
|
|
688
|
+
});
|
|
689
|
+
|
|
690
|
+
// Legacy format (still supported)
|
|
691
|
+
await createCli(mainCommand, {
|
|
692
|
+
fileBased: {
|
|
597
693
|
enable: true, // Enables file-based command detection.
|
|
598
694
|
cmdsRootPath: "app", // Directory to scan for commands.
|
|
599
695
|
},
|
|
@@ -634,7 +730,7 @@ Finally, a full-featured CLI launcher without the ceremony. `@reliverse/rempts`'
|
|
|
634
730
|
Seamlessly combines positional and named arguments with zero configuration, auto-parsing booleans, strings, numbers, arrays, and even supporting negated flags like `--no-flag`.
|
|
635
731
|
|
|
636
732
|
- **Customizable Behavior:**
|
|
637
|
-
Options such as `
|
|
733
|
+
Options such as `fileBased.enable`, `cmdsRootPath`, and `autoExit` allow you to tailor the launcher's behavior. For example, you can choose whether the process should exit automatically on error or allow manual error handling.
|
|
638
734
|
|
|
639
735
|
- **Error Management & Usage Output:**
|
|
640
736
|
The launcher provides clear error messages for missing required arguments, invalid types, or command import issues, and it automatically displays usage information for your CLI.
|
|
@@ -833,7 +929,7 @@ export default defineCommand({
|
|
|
833
929
|
Below is a demonstration of how to define and use all supported argument types in rempts: positional, boolean, string, number, and array. This includes example CLI invocations and the resulting parsed output.
|
|
834
930
|
|
|
835
931
|
```ts
|
|
836
|
-
import { defineCommand,
|
|
932
|
+
import { defineCommand, createCli } from "@reliverse/rempts";
|
|
837
933
|
|
|
838
934
|
const main = defineCommand({
|
|
839
935
|
meta: {
|
|
@@ -877,7 +973,13 @@ const main = defineCommand({
|
|
|
877
973
|
},
|
|
878
974
|
});
|
|
879
975
|
|
|
880
|
-
|
|
976
|
+
// New object format (recommended)
|
|
977
|
+
await createCli({
|
|
978
|
+
mainCommand: main,
|
|
979
|
+
});
|
|
980
|
+
|
|
981
|
+
// Legacy format (still supported)
|
|
982
|
+
await createCli(main);
|
|
881
983
|
```
|
|
882
984
|
|
|
883
985
|
### Example CLI Invocations
|
|
@@ -1048,13 +1150,7 @@ The validation happens after type casting, so for example with numbers, the inpu
|
|
|
1048
1150
|
|
|
1049
1151
|
Bug report? Prompt idea? Want to build the best DX possible?
|
|
1050
1152
|
|
|
1051
|
-
You're in the right place
|
|
1052
|
-
|
|
1053
|
-
- ✨ [Star the repo](https://github.com/reliverse/rempts)
|
|
1054
|
-
- 💬 [Join the Discord](https://discord.gg/3GawfWfAPe)
|
|
1055
|
-
- ❤️ [Sponsor @blefnk](https://github.com/sponsors/blefnk)
|
|
1056
|
-
|
|
1057
|
-
> *No classes. No magic. Just clean, composable tools for CLI devs.*
|
|
1153
|
+
You're in the right place! Please help us make the best CLI toolkit possible.
|
|
1058
1154
|
|
|
1059
1155
|
### Notices For Contributors
|
|
1060
1156
|
|
|
@@ -1078,6 +1174,10 @@ All APIs are fully typed. See [`src/types.ts`](./src/types.ts) for advanced cust
|
|
|
1078
1174
|
|
|
1079
1175
|
- [CLI application with the Node.js Readline module](https://dev.to/camptocamp-geo/cli-application-with-the-nodejs-readline-module-48ic)
|
|
1080
1176
|
|
|
1177
|
+
## TODO
|
|
1178
|
+
|
|
1179
|
+
- [ ] migrate to `dler libs` in the future (all main components will be published as separate packages; `@reliverse/rempts` will be a wrapper for all of them)
|
|
1180
|
+
|
|
1081
1181
|
## Related
|
|
1082
1182
|
|
|
1083
1183
|
- [`@reliverse/cli`](https://npmjs.com/package/@reliverse/cli) – CLI-first toolkit for fullstack workflows
|
|
@@ -1089,6 +1189,18 @@ All APIs are fully typed. See [`src/types.ts`](./src/types.ts) for advanced cust
|
|
|
1089
1189
|
|
|
1090
1190
|
- [citty](https://github.com/unjs/citty#readme) - launcher design inspiration
|
|
1091
1191
|
|
|
1192
|
+
## Support
|
|
1193
|
+
|
|
1194
|
+
Bug report? Prompt idea? Want to build the best DX possible?
|
|
1195
|
+
|
|
1196
|
+
You're in the right place:
|
|
1197
|
+
|
|
1198
|
+
- ✨ [Star the repo](https://github.com/reliverse/rempts)
|
|
1199
|
+
- 💬 [Join the Discord](https://discord.gg/3GawfWfAPe)
|
|
1200
|
+
- ❤️ [Sponsor @blefnk](https://github.com/sponsors/blefnk)
|
|
1201
|
+
|
|
1202
|
+
> *No classes. No magic. Just clean, composable tools for CLI devs.*
|
|
1203
|
+
|
|
1092
1204
|
## License
|
|
1093
1205
|
|
|
1094
|
-
💖 MIT © [blefnk (Nazar Kornienko)](https://github.com/blefnk)
|
|
1206
|
+
💖 MIT (see [LICENSE](./LICENSE) and [LICENCES](./LICENSES)) © [blefnk (Nazar Kornienko)](https://github.com/blefnk)
|
|
@@ -3,10 +3,7 @@ import {
|
|
|
3
3
|
} from "@figliolia/chalk-animation";
|
|
4
4
|
import { relinka } from "@reliverse/relinka";
|
|
5
5
|
import { msg } from "../msg-fmt/messages.js";
|
|
6
|
-
import {
|
|
7
|
-
deleteLastLine,
|
|
8
|
-
getTerminalWidth
|
|
9
|
-
} from "../msg-fmt/terminal.js";
|
|
6
|
+
import { deleteLastLine, getTerminalWidth } from "../msg-fmt/terminal.js";
|
|
10
7
|
export const animationMap = {
|
|
11
8
|
rainbow: ChalkAnimation.rainbow,
|
|
12
9
|
pulse: ChalkAnimation.pulse,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import logUpdate from "log-update";
|
|
2
2
|
import { cursor } from "sisteransi";
|
|
3
3
|
import { fmt } from "../msg-fmt/messages.js";
|
|
4
|
-
import { outroPrompt } from "../outro/outro-
|
|
5
|
-
import { streamText } from "
|
|
4
|
+
import { outroPrompt } from "../outro/outro-mod.js";
|
|
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;
|
|
8
8
|
const terminal = {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const confirm: any;
|
|
@@ -3,7 +3,7 @@ import { stdin as input, stdout as output } from "node:process";
|
|
|
3
3
|
import readline from "node:readline/promises";
|
|
4
4
|
import { bar, msg } from "../msg-fmt/messages.js";
|
|
5
5
|
import { deleteLastLine } from "../msg-fmt/terminal.js";
|
|
6
|
-
import { completePrompt } from "
|
|
6
|
+
import { completePrompt } from "../utils/prompt-end.js";
|
|
7
7
|
function renderPrompt(params) {
|
|
8
8
|
const {
|
|
9
9
|
title,
|
|
@@ -192,11 +192,11 @@ function renderEditor() {
|
|
|
192
192
|
const lineNum = String(fileLineIndex + 1).padStart(3);
|
|
193
193
|
term(state.theme.lineNumber(`${lineNum} `));
|
|
194
194
|
const line = state.lines[fileLineIndex];
|
|
195
|
-
const displayLine = line
|
|
195
|
+
const displayLine = line?.substring(
|
|
196
196
|
state.leftCol,
|
|
197
197
|
state.leftCol + displayWidth
|
|
198
198
|
);
|
|
199
|
-
const highlightedDisplayLine = applySyntaxHighlighting(displayLine);
|
|
199
|
+
const highlightedDisplayLine = applySyntaxHighlighting(displayLine ?? "");
|
|
200
200
|
term(highlightedDisplayLine);
|
|
201
201
|
term.eraseLineAfter();
|
|
202
202
|
} else {
|
|
@@ -237,8 +237,8 @@ function deleteCharBackward() {
|
|
|
237
237
|
const currentLine = state.lines.splice(state.cursorY, 1)[0];
|
|
238
238
|
state.cursorY--;
|
|
239
239
|
const prevLine = state.lines[state.cursorY];
|
|
240
|
-
state.cursorX = prevLine
|
|
241
|
-
state.lines[state.cursorY] = prevLine + currentLine;
|
|
240
|
+
state.cursorX = prevLine?.length ?? 0;
|
|
241
|
+
state.lines[state.cursorY] = prevLine + (currentLine ?? "");
|
|
242
242
|
updateModifiedStatus();
|
|
243
243
|
}
|
|
244
244
|
}
|
|
@@ -368,7 +368,7 @@ async function confirmAction(promptMessage = "Are you sure? (y/N)") {
|
|
|
368
368
|
no: ["n", "N", "ENTER"]
|
|
369
369
|
}).promise;
|
|
370
370
|
term.moveTo(1, term.height).eraseLine();
|
|
371
|
-
return confirm;
|
|
371
|
+
return confirm ?? false;
|
|
372
372
|
} catch (_error) {
|
|
373
373
|
term.moveTo(1, term.height).eraseLine();
|
|
374
374
|
state.statusMessage = "Cancelled";
|
|
@@ -537,7 +537,7 @@ async function findText() {
|
|
|
537
537
|
for (let y = state.cursorY; y < state.lines.length; y++) {
|
|
538
538
|
const line = state.lines[y];
|
|
539
539
|
const startIdx = y === state.cursorY ? state.cursorX + 1 : 0;
|
|
540
|
-
const matchIndex = line
|
|
540
|
+
const matchIndex = line?.indexOf(termToUse, startIdx) ?? -1;
|
|
541
541
|
if (matchIndex !== -1) {
|
|
542
542
|
state.cursorY = y;
|
|
543
543
|
state.cursorX = matchIndex;
|
|
@@ -549,8 +549,8 @@ async function findText() {
|
|
|
549
549
|
state.statusMessage = `Search wrapped: ${termToUse}`;
|
|
550
550
|
for (let y = 0; y <= state.cursorY; y++) {
|
|
551
551
|
const line = state.lines[y];
|
|
552
|
-
const endIdx = y === state.cursorY ? state.cursorX + 1 : line
|
|
553
|
-
const matchIndex = line
|
|
552
|
+
const endIdx = y === state.cursorY ? state.cursorX + 1 : line?.length ?? 0;
|
|
553
|
+
const matchIndex = line?.substring(0, endIdx).indexOf(termToUse) ?? -1;
|
|
554
554
|
if (matchIndex !== -1) {
|
|
555
555
|
state.cursorY = y;
|
|
556
556
|
state.cursorX = matchIndex;
|
|
@@ -229,7 +229,7 @@ export declare const mainSymbols: {
|
|
|
229
229
|
lineSlash: string;
|
|
230
230
|
};
|
|
231
231
|
export declare const fallbackSymbols: Record<string, string>;
|
|
232
|
-
declare const figures: {
|
|
232
|
+
export declare const figures: Record<string, string> | {
|
|
233
233
|
tick: string;
|
|
234
234
|
info: string;
|
|
235
235
|
warning: string;
|
|
@@ -458,5 +458,4 @@ declare const figures: {
|
|
|
458
458
|
lineCross: string;
|
|
459
459
|
lineBackslash: string;
|
|
460
460
|
lineSlash: string;
|
|
461
|
-
}
|
|
462
|
-
export default figures;
|
|
461
|
+
};
|
|
@@ -282,5 +282,4 @@ export const fallbackSymbols = {
|
|
|
282
282
|
...specialFallbackSymbols
|
|
283
283
|
};
|
|
284
284
|
const shouldUseMain = isUnicodeSupported();
|
|
285
|
-
const figures = shouldUseMain ? mainSymbols : fallbackSymbols;
|
|
286
|
-
export default figures;
|
|
285
|
+
export const figures = shouldUseMain ? mainSymbols : fallbackSymbols;
|
|
@@ -3,8 +3,8 @@ import { isUnicodeSupported } from "@reliverse/runtime";
|
|
|
3
3
|
import readline from "node:readline/promises";
|
|
4
4
|
import { bar, msg, msgUndoAll } from "../msg-fmt/messages.js";
|
|
5
5
|
import { deleteLastLine } from "../msg-fmt/terminal.js";
|
|
6
|
-
import { completePrompt } from "
|
|
7
|
-
import { streamText } from "
|
|
6
|
+
import { completePrompt } from "../utils/prompt-end.js";
|
|
7
|
+
import { streamText } from "../utils/stream-text.js";
|
|
8
8
|
const unicode = isUnicodeSupported();
|
|
9
9
|
const S_MASK = unicode ? "\u258B" : "*";
|
|
10
10
|
function getMaskChar(customMask) {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { relinka } from "@reliverse/relinka";
|
|
2
2
|
import { getCurrentTerminalName } from "@reliverse/runtime";
|
|
3
|
-
import { createAsciiArt } from "../ascii-art/ascii-art.js";
|
|
4
3
|
import { msg } from "../msg-fmt/messages.js";
|
|
5
4
|
import {
|
|
6
5
|
getExactTerminalWidth,
|
|
@@ -11,8 +10,9 @@ import {
|
|
|
11
10
|
preventWrongTerminalSize,
|
|
12
11
|
preventWindowsHomeDirRoot,
|
|
13
12
|
preventUnsupportedTTY
|
|
14
|
-
} from "
|
|
15
|
-
import { pm, reliversePrompts } from "
|
|
13
|
+
} from "../utils/prevent.js";
|
|
14
|
+
import { pm, reliversePrompts } from "../utils/system.js";
|
|
15
|
+
import { createAsciiArt } from "../visual/visual-mod.js";
|
|
16
16
|
export async function introPrompt(optionsOrTitle) {
|
|
17
17
|
const options = typeof optionsOrTitle === "string" ? { title: optionsOrTitle } : optionsOrTitle;
|
|
18
18
|
const {
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type { ReliArgParserOptions } from "@reliverse/reliarg";
|
|
2
|
+
import type { ArgDefinitions, Command, DefineCommandOptions, EmptyArgs, FileBasedOptions } from "./launcher-types.js";
|
|
3
|
+
import type { AnyRouter } from "./trpc-orpc-support/trpc-compat.js";
|
|
4
|
+
import type { Logger, OmeletteInstanceLike, Promptable } from "./trpc-orpc-support/types.js";
|
|
5
|
+
/**
|
|
6
|
+
* Defines a command with metadata, argument definitions,
|
|
7
|
+
* an execution function, and (optional) subCommands.
|
|
8
|
+
*/
|
|
9
|
+
export declare function defineCommand<A extends ArgDefinitions = EmptyArgs>(options: DefineCommandOptions<A>): Command<A>;
|
|
10
|
+
/**
|
|
11
|
+
* Show usage for a given command.
|
|
12
|
+
*/
|
|
13
|
+
export declare function showUsage<A extends ArgDefinitions>(command: Command<A>, parserOptions?: ReliArgParserOptions & {
|
|
14
|
+
fileBased?: FileBasedOptions;
|
|
15
|
+
autoExit?: boolean;
|
|
16
|
+
metaSettings?: {
|
|
17
|
+
showDescriptionOnMain?: boolean;
|
|
18
|
+
};
|
|
19
|
+
_fileBasedCurrentDir?: string;
|
|
20
|
+
_fileBasedPathSegments?: string[];
|
|
21
|
+
_isSubcommand?: boolean;
|
|
22
|
+
}, globalCliMeta?: {
|
|
23
|
+
name?: string;
|
|
24
|
+
version?: string;
|
|
25
|
+
description?: string;
|
|
26
|
+
}): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Primary entry point to run a command. This function supports:
|
|
29
|
+
*
|
|
30
|
+
* - File-based Commands: scanning for commands within a given commands root.
|
|
31
|
+
* - Commands defined within the command object.
|
|
32
|
+
* - Standard flags like --help, --version, and --debug.
|
|
33
|
+
* - RPC functionality: tRPC/oRPC router integration with automatic CLI generation.
|
|
34
|
+
*
|
|
35
|
+
* This function passes along remaining arguments to command runners to ensure
|
|
36
|
+
* consistent parsing.
|
|
37
|
+
*/
|
|
38
|
+
export declare function createCli<A extends ArgDefinitions = EmptyArgs>(options: Command<A> | {
|
|
39
|
+
name?: string;
|
|
40
|
+
version?: string;
|
|
41
|
+
description?: string;
|
|
42
|
+
mainCommand?: Command<A>;
|
|
43
|
+
fileBased?: FileBasedOptions;
|
|
44
|
+
autoExit?: boolean;
|
|
45
|
+
metaSettings?: {
|
|
46
|
+
showDescriptionOnMain?: boolean;
|
|
47
|
+
};
|
|
48
|
+
meta?: Command<A>["meta"];
|
|
49
|
+
args?: Command<A>["args"];
|
|
50
|
+
run?: Command<A>["run"];
|
|
51
|
+
commands?: Command<A>["commands"];
|
|
52
|
+
onCmdInit?: Command<A>["onCmdInit"];
|
|
53
|
+
onCmdExit?: Command<A>["onCmdExit"];
|
|
54
|
+
onLauncherInit?: Command<A>["onLauncherInit"];
|
|
55
|
+
onLauncherExit?: Command<A>["onLauncherExit"];
|
|
56
|
+
rpc?: {
|
|
57
|
+
/** A tRPC router. Procedures will become CLI commands. */
|
|
58
|
+
router: AnyRouter;
|
|
59
|
+
/** Context to be supplied when invoking the router. */
|
|
60
|
+
context?: any;
|
|
61
|
+
/** The `@trpc/server` module to use for calling procedures. Required when using trpc v10. */
|
|
62
|
+
trpcServer?: any | Promise<any>;
|
|
63
|
+
/** Usage code examples to display in `--help` output. */
|
|
64
|
+
usage?: string | string[];
|
|
65
|
+
/** Dependencies for schema validation libraries */
|
|
66
|
+
"@valibot/to-json-schema"?: {
|
|
67
|
+
toJsonSchema: (input: unknown, options?: {
|
|
68
|
+
errorMode?: "throw" | "ignore" | "warn";
|
|
69
|
+
}) => any;
|
|
70
|
+
};
|
|
71
|
+
effect?: {
|
|
72
|
+
Schema: {
|
|
73
|
+
isSchema: (input: unknown) => input is "JSONSchemaMakeable";
|
|
74
|
+
};
|
|
75
|
+
JSONSchema: {
|
|
76
|
+
make: (input: "JSONSchemaMakeable") => any;
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
rpcRunParams?: {
|
|
81
|
+
argv?: string[];
|
|
82
|
+
logger?: Logger;
|
|
83
|
+
completion?: OmeletteInstanceLike | (() => Promise<OmeletteInstanceLike>);
|
|
84
|
+
prompts?: Promptable;
|
|
85
|
+
/** Format an error thrown by the root procedure before logging to `logger.error` */
|
|
86
|
+
formatError?: (error: unknown) => string;
|
|
87
|
+
process?: {
|
|
88
|
+
exit: (code: number) => never;
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
}, legacyParserOptions?: ReliArgParserOptions & {
|
|
92
|
+
fileBased?: FileBasedOptions;
|
|
93
|
+
autoExit?: boolean;
|
|
94
|
+
metaSettings?: {
|
|
95
|
+
showDescriptionOnMain?: boolean;
|
|
96
|
+
};
|
|
97
|
+
}): Promise<void> & {
|
|
98
|
+
run(_ctx?: any): Promise<void>;
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Helper to define argument definitions with improved type inference
|
|
102
|
+
* for IntelliSense and validation for array defaults against options.
|
|
103
|
+
*/
|
|
104
|
+
export declare function defineArgs<A extends ArgDefinitions>(args: A): A;
|
|
105
|
+
/**
|
|
106
|
+
* Programmatically run a command's run() handler with parsed arguments.
|
|
107
|
+
* Does not handle subcommands, file-based commands, or global hooks.
|
|
108
|
+
* Suitable for use in demos, tests, or programmatic invocation.
|
|
109
|
+
*
|
|
110
|
+
* @param command The command definition (from defineCommand)
|
|
111
|
+
* @param argv The argv array to parse (default: [])
|
|
112
|
+
* @param parserOptions Optional reliArgParser options
|
|
113
|
+
*/
|
|
114
|
+
export declare function runCmd<A extends ArgDefinitions = EmptyArgs>(command: Command<A>, argv?: string[], parserOptions?: ReliArgParserOptions): Promise<void>;
|