@reliverse/rempts 1.7.7 → 1.7.8

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
@@ -155,7 +155,7 @@ await main();
155
155
  ```ts
156
156
  import { relinka } from "@reliverse/relinka";
157
157
 
158
- import { defineCommand, runMain } from "~/mod.js";
158
+ import { defineCommand, runMain } from "@reliverse/rempts";
159
159
 
160
160
  const main = defineCommand({
161
161
  meta: {
@@ -238,7 +238,7 @@ defineCommand({
238
238
  args: {
239
239
  name: { type: "string", required: true },
240
240
  verbose: { type: "boolean", default: false },
241
- animals: { type: "array", options: ["cat","dog"] },
241
+ animals: { type: "array", default: ["cat","dog"] },
242
242
  },
243
243
  async run({ args, raw }) { // or `async run(ctx)`
244
244
  relinka("log", args.name, args.verbose, args.animals); // or `relinka("log", ctx.args.name, ...);`
@@ -283,7 +283,7 @@ When playing with the example, you can run e.g. `bun dev:modern nested foo bar b
283
283
  git clone https://github.com/reliverse/rempts
284
284
  cd rempts
285
285
  bun i
286
- bun dev # supported options: name
286
+ bun dev
287
287
  ```
288
288
 
289
289
  - `bun dev:prompts`: This example will show you a `multiselectPrompt()` where you can choose which CLI prompts you want to play with.
@@ -563,12 +563,12 @@ Finally, a full-featured CLI launcher without the ceremony. `@reliverse/rempts`'
563
563
 
564
564
  - **Lifecycle Hooks:**
565
565
  You can define optional lifecycle hooks in your main command:
566
- - `onLauncherStart` and `onLauncherEnd` (global, called once per CLI process)
566
+ - `onLauncherInit` and `onLauncherExit` (global, called once per CLI process)
567
567
  - `onCmdInit` and `onCmdExit` (per-command, called before/after each command, but NOT for the main `run()` handler)
568
568
 
569
569
  **Global Hooks:**
570
- - `onLauncherStart`: Called once, before any command/run() is executed.
571
- - `onLauncherEnd`: Called once, after all command/run() logic is finished (even if an error occurs).
570
+ - `onLauncherInit`: Called once, before any command/run() is executed.
571
+ - `onLauncherExit`: Called once, after all command/run() logic is finished (even if an error occurs).
572
572
 
573
573
  **Per-Command Hooks:**
574
574
  - `onCmdInit`: Called before each command (not for main `run()`).
@@ -578,20 +578,20 @@ Finally, a full-featured CLI launcher without the ceremony. `@reliverse/rempts`'
578
578
  - If your CLI has multiple commands, `onCmdInit` and `onCmdExit` will be called for each command invocation, not just once for the whole CLI process.
579
579
  - If your main command has a `run()` handler (and no command is invoked), these hooks are **not** called; use the `run()` handler itself or the global hooks for such logic.
580
580
  - This allows you to perform setup/teardown logic specific to each command execution.
581
- - If you want logic to run only once for the entire CLI process, use `onLauncherStart` and `onLauncherEnd`.
581
+ - If you want logic to run only once for the entire CLI process, use `onLauncherInit` and `onLauncherExit`.
582
582
 
583
583
  **Example:**
584
584
 
585
585
  ```ts
586
586
  const main = defineCommand({
587
- onLauncherStart() { relinka('info', 'Global setup (once per process)'); },
588
- onLauncherEnd() { relinka('info', 'Global cleanup (once per process)'); },
587
+ onLauncherInit() { relinka('info', 'Global setup (once per process)'); },
588
+ onLauncherExit() { relinka('info', 'Global cleanup (once per process)'); },
589
589
  onCmdInit() { relinka('info', 'Setup for each command'); },
590
590
  onCmdExit() { relinka('info', 'Cleanup for each command'); },
591
591
  commands: { ... },
592
592
  run() { relinka('info', 'Main run handler (no command)'); },
593
593
  });
594
- // onLauncherStart/onLauncherEnd are called once per process
594
+ // onLauncherInit/onLauncherExit are called once per process
595
595
  // onCmdInit/onCmdExit are called for every command (not for main run())
596
596
  // If you want per-run() logic, use the run() handler or global hooks
597
597
  ```
@@ -627,7 +627,63 @@ Finally, a full-featured CLI launcher without the ceremony. `@reliverse/rempts`'
627
627
 
628
628
  ### Launcher Programmatic Execution
629
629
 
630
- For larger CLIs or when you want to programmatically run commands (e.g.: [prompt demo](./example/prompts/mod.ts), tests, etc), you can organize your commands in a `cmds.ts` file and use the `runCmd` utility.
630
+ For larger CLIs or when you want to programmatically run commands (e.g.: [prompt demo](./example/prompts/mod.ts), tests, etc), you can organize your commands in a `cmds.ts` file and use the `runCmd` utility. Example:
631
+
632
+ ```ts
633
+ // example/launcher/app/runcmd/cmd.ts
634
+
635
+ import { relinka } from "@reliverse/relinka";
636
+ import { defineArgs, defineCommand, runCmd } from "@reliverse/rempts";
637
+ import { cmdMinimal } from "../cmds.js";
638
+
639
+ export default defineCommand({
640
+ meta: {
641
+ name: "runcmd",
642
+ description:
643
+ "Demonstrate how to use runCmd() to invoke another command programmatically.",
644
+ },
645
+ args: defineArgs({
646
+ name: {
647
+ type: "string",
648
+ description: "your name",
649
+ },
650
+ }),
651
+ async run({ args }) {
652
+ // const username = args.name ?? "Alice";
653
+ const username = args.name; // intentionally missing fallback
654
+ relinka(
655
+ "info",
656
+ `Running the 'minimal' command using runCmd() with name='${username}'`,
657
+ );
658
+ await runCmd(await cmdMinimal(), ["--name", username]);
659
+ relinka("log", "Done running 'minimal' via runCmd().");
660
+ },
661
+ });
662
+ ```
663
+
664
+ ```ts
665
+ // example/launcher/app/minimal/cmd.ts
666
+
667
+ import { relinka } from "@reliverse/relinka";
668
+ import { defineArgs, defineCommand } from "@reliverse/rempts";
669
+
670
+ export default defineCommand({
671
+ meta: {
672
+ name: "minimal",
673
+ description: "hello world",
674
+ },
675
+ args: defineArgs({
676
+ name: {
677
+ type: "string",
678
+ description: "your name",
679
+ required: true,
680
+ },
681
+ }),
682
+ run({ args }) {
683
+ relinka("success", `👋 Hello, ${args.name}!`);
684
+ },
685
+ });
686
+ ```
631
687
 
632
688
  **Pro Tips & Best Practices**:
633
689
 
@@ -641,7 +697,7 @@ For larger CLIs or when you want to programmatically run commands (e.g.: [prompt
641
697
  ```ts
642
698
  // example/launcher/app/cmds.ts
643
699
 
644
- export async function getCmdHooks() {
700
+ export async function cmdHooks() {
645
701
  return (await import("./hooks/cmd.js")).default;
646
702
  }
647
703
 
@@ -657,12 +713,12 @@ Usage:
657
713
  ```ts
658
714
  // example/prompts/mod.ts
659
715
 
660
- import { getCmdHooks } from "@/launcher/app/cmds.js";
716
+ import { cmdHooks } from "@/launcher/app/cmds.js";
661
717
  import { runCmd } from "@reliverse/rempts";
662
718
 
663
- await runCmd(await getCmdHooks(), ["--flag"]);
719
+ await runCmd(await cmdHooks(), ["--flag"]);
664
720
  // OR:
665
- // const hooksCmd = await getCmdHooks();
721
+ // const hooksCmd = await cmdHooks();
666
722
  // await runCmd(hooksCmd, ["--flag"]);
667
723
  ```
668
724
 
@@ -698,7 +754,7 @@ await runCmd(hooksCmd, ["--flag"]); // argv as array of strings
698
754
  Or with lazy loading:
699
755
 
700
756
  ```ts
701
- const hooksCmd = await getCmdHooks();
757
+ const hooksCmd = await cmdHooks();
702
758
  await runCmd(hooksCmd, ["--flag"]);
703
759
  ```
704
760
 
@@ -711,6 +767,162 @@ await runCmd(hooksCmd, ["--flag"]);
711
767
 
712
768
  Choose the pattern that best fits your CLI's size and usage!
713
769
 
770
+ ## Argument Types: Usage Comparison
771
+
772
+ 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.
773
+
774
+ ```ts
775
+ import { defineCommand, runMain } from "@reliverse/rempts";
776
+
777
+ const main = defineCommand({
778
+ meta: {
779
+ name: "mycli",
780
+ version: "1.0.0",
781
+ description: "Demo of all argument types",
782
+ },
783
+ args: {
784
+ // Positional argument (required)
785
+ input: {
786
+ type: "positional",
787
+ required: true,
788
+ description: "Input file path",
789
+ },
790
+ // Boolean flag (default: false)
791
+ verbose: {
792
+ type: "boolean",
793
+ default: false,
794
+ description: "Enable verbose output",
795
+ },
796
+ // String option (optional)
797
+ name: {
798
+ type: "string",
799
+ description: "Your name",
800
+ },
801
+ // Number option (optional, with default)
802
+ count: {
803
+ type: "number",
804
+ default: 1,
805
+ description: "How many times to run",
806
+ },
807
+ // Array option (can be repeated, accepts any value)
808
+ tags: {
809
+ type: "array",
810
+ default: ["demo"],
811
+ description: "Tags for this run (repeatable)",
812
+ },
813
+ },
814
+ run({ args }) {
815
+ console.log("Parsed args:", args);
816
+ },
817
+ });
818
+
819
+ await runMain(main);
820
+ ```
821
+
822
+ ### Example CLI Invocations
823
+
824
+ #### 1. Positional argument
825
+
826
+ ```bash
827
+ mycli input.txt
828
+ # → args.input = "input.txt"
829
+ ```
830
+
831
+ #### 2. Boolean flag
832
+
833
+ ```bash
834
+ mycli input.txt --verbose
835
+ # → args.verbose = true
836
+ mycli input.txt --no-verbose
837
+ # → args.verbose = false
838
+ ```
839
+
840
+ #### 3. String option
841
+
842
+ ```bash
843
+ mycli input.txt --name Alice
844
+ # → args.name = "Alice"
845
+ mycli input.txt
846
+ # → args.name = undefined
847
+ ```
848
+
849
+ #### 4. Number option
850
+
851
+ ```bash
852
+ mycli input.txt --count 5
853
+ # → args.count = 5
854
+ mycli input.txt
855
+ # → args.count = 1 (default)
856
+ ```
857
+
858
+ #### 5. Array option (repeatable, accepts any value)
859
+
860
+ You can provide array values using any of the following syntaxes (mix and match as needed):
861
+
862
+ - Repeated flags:
863
+
864
+ ```bash
865
+ mycli input.txt --tags foo --tags bar --tags baz
866
+ # → args.tags = ["foo", "bar", "baz"]
867
+ ```
868
+
869
+ - Comma-separated values (with or without spaces):
870
+
871
+ ```bash
872
+ mycli input.txt --tags foo,bar,baz
873
+ mycli input.txt --tags foo, bar, baz
874
+ # → args.tags = ["foo", "bar", "baz"]
875
+ ```
876
+
877
+ - Bracketed values (must be passed as a single argument!):
878
+
879
+ ```bash
880
+ mycli input.txt --tags "[foo,bar,baz]"
881
+ # → args.tags = ["foo", "bar", "baz"]
882
+ ```
883
+
884
+ - Mix and match:
885
+
886
+ ```bash
887
+ mycli input.txt --tags foo --tags "[bar,bar2,bar3]" --tags baz
888
+ # → args.tags = ["foo", "bar", "bar2", "bar3", "baz"]
889
+ ```
890
+
891
+ > **Important:**
892
+ >
893
+ > - **Quoted values (single or double quotes around elements) are NOT supported and will throw an error.**
894
+ > - Example: `--tags 'foo'` or `--tags "[\"bar\",'baz']"` will throw an error.
895
+ > - **Bracketed or comma-separated lists must be passed as a single argument.**
896
+ > - Example: `--tags "[foo,bar]"` (quotes around the whole value, not around elements)
897
+ > - If you split a bracketed value across arguments, you will get a warning or incorrect parsing.
898
+ > - **Shells remove quotes before passing arguments to the CLI.** If you want to pass a value with commas or brackets, always quote the whole value.
899
+ > - **Troubleshooting:**
900
+ > - If you see a warning about possible shell splitting, try quoting the whole value: `--tags "[a,b,c]"`
901
+ > - If you see an error about quoted values, remove quotes around individual elements.
902
+
903
+ **Example error:**
904
+
905
+ ```bash
906
+ $ bun example/launcher/modern.ts build --entry "[foo.ts," "bar.ts]"
907
+ ✖ Don't use quotes around array elements.
908
+ ✖ Also — don't use spaces — unless you wrap the whole array in quotes.
909
+ ⚠ Array argument --entry: Detected possible shell splitting of bracketed value ('[foo.ts,').
910
+ ⚠ If you intended to pass a bracketed list, quote the whole value like: --entry "[a, b, c]"
911
+ ```
912
+
913
+ #### 6. All together
914
+
915
+ ```bash
916
+ mycli input.txt --verbose --name Alice --count 3 --tags foo --tags bar
917
+ # → args = {
918
+ # input: "input.txt",
919
+ # verbose: true,
920
+ # name: "Alice",
921
+ # count: 3,
922
+ # tags: ["foo", "bar"]
923
+ # }
924
+ ```
925
+
714
926
  ## Contributing
715
927
 
716
928
  Bug report? Prompt idea? Want to build the best DX possible?
@@ -1,8 +1,4 @@
1
1
  import type { ReliArgParserOptions } from "@reliverse/reliarg";
2
- type InvalidDefaultError<O extends readonly string[]> = {
3
- __error__: "Default value(s) must be a subset of options";
4
- options: O;
5
- };
6
2
  type EmptyArgs = Record<string, never>;
7
3
  type BaseArgProps = {
8
4
  description?: string;
@@ -27,7 +23,6 @@ type NumberArgDefinition = {
27
23
  type ArrayArgDefinition = {
28
24
  type: "array";
29
25
  default?: string | readonly string[];
30
- options: readonly string[];
31
26
  } & BaseArgProps;
32
27
  export type ArgDefinition = PositionalArgDefinition | BooleanArgDefinition | StringArgDefinition | NumberArgDefinition | ArrayArgDefinition;
33
28
  export type ArgDefinitions = Record<string, ArgDefinition>;
@@ -85,11 +80,11 @@ type DefineCommandOptions<A extends ArgDefinitions = EmptyArgs> = {
85
80
  /**
86
81
  * Called once per CLI process, before any command/run() is executed
87
82
  */
88
- onLauncherStart?: () => void | Promise<void>;
83
+ onLauncherInit?: () => void | Promise<void>;
89
84
  /**
90
85
  * Called once per CLI process, after all command/run() logic is finished
91
86
  */
92
- onLauncherEnd?: () => void | Promise<void>;
87
+ onLauncherExit?: () => void | Promise<void>;
93
88
  };
94
89
  export type Command<A extends ArgDefinitions = EmptyArgs> = {
95
90
  meta?: CommandMeta;
@@ -122,28 +117,16 @@ export type Command<A extends ArgDefinitions = EmptyArgs> = {
122
117
  /**
123
118
  * Called once per CLI process, before any command/run() is executed
124
119
  */
125
- onLauncherStart?: () => void | Promise<void>;
120
+ onLauncherInit?: () => void | Promise<void>;
126
121
  /**
127
122
  * Called once per CLI process, after all command/run() logic is finished
128
123
  */
129
- onLauncherEnd?: () => void | Promise<void>;
124
+ onLauncherExit?: () => void | Promise<void>;
130
125
  };
131
126
  export type InferArgTypes<A extends ArgDefinitions> = {
132
127
  [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 {
133
128
  type: "array";
134
- options: infer O extends readonly string[];
135
- } ? O[number][] : never;
136
- };
137
- type ValidateArrayDefaults<A extends ArgDefinitions> = {
138
- [K in keyof A]: A[K] extends {
139
- type: "array";
140
- options: infer O extends readonly string[];
141
- default?: infer D;
142
- } ? D extends undefined ? A[K] : D extends O[number] ? A[K] : D extends readonly (infer E)[] ? E extends O[number] ? A[K] : Omit<A[K], "default"> & {
143
- default: InvalidDefaultError<O>;
144
- } : Omit<A[K], "default"> & {
145
- default: InvalidDefaultError<O>;
146
- } : A[K];
129
+ } ? string[] : never;
147
130
  };
148
131
  export type FileBasedCmdsOptions = {
149
132
  enable: boolean;
@@ -187,11 +170,8 @@ export declare function runMain<A extends ArgDefinitions = EmptyArgs>(command: C
187
170
  /**
188
171
  * Helper to define argument definitions with improved type inference
189
172
  * for IntelliSense and validation for array defaults against options.
190
- *
191
- * **Note:** For array types, use `as const` on the `options` array to enable
192
- * precise default value validation (e.g., `options: ["a", "b"] as const`).
193
173
  */
194
- export declare function defineArgs<A extends ArgDefinitions>(args: A & ValidateArrayDefaults<A>): A;
174
+ export declare function defineArgs<A extends ArgDefinitions>(args: A): A;
195
175
  /**
196
176
  * Programmatically run a command's run() handler with parsed arguments.
197
177
  * Does not handle subcommands, file-based commands, or global hooks.
@@ -36,11 +36,7 @@ function buildExampleArgs(args) {
36
36
  parts.push(`--${key}=${String(def.default ?? 42)}`);
37
37
  break;
38
38
  case "array":
39
- if (def.options && def.options.length > 0) {
40
- parts.push(`--${key}=${String(def.options[0])}`);
41
- } else {
42
- parts.push(`--${key}=${String(key)}`);
43
- }
39
+ parts.push(`--${key}=${String(def.default ?? key)}`);
44
40
  break;
45
41
  }
46
42
  }
@@ -59,8 +55,8 @@ function isFlag(str) {
59
55
  export function defineCommand(options) {
60
56
  const onCmdInit = options.onCmdInit || options.setup;
61
57
  const onCmdExit = options.onCmdExit || options.cleanup;
62
- const onLauncherStart = options.onLauncherStart;
63
- const onLauncherEnd = options.onLauncherEnd;
58
+ const onLauncherInit = options.onLauncherInit;
59
+ const onLauncherExit = options.onLauncherExit;
64
60
  let commands = options.commands;
65
61
  if (!commands) {
66
62
  commands = options.subCommands;
@@ -72,8 +68,8 @@ export function defineCommand(options) {
72
68
  commands,
73
69
  onCmdInit,
74
70
  onCmdExit,
75
- onLauncherStart,
76
- onLauncherEnd,
71
+ onLauncherInit,
72
+ onLauncherExit,
77
73
  // Backward-compatible aliases
78
74
  setup: onCmdInit,
79
75
  cleanup: onCmdExit
@@ -245,15 +241,13 @@ export async function showUsage(command, parserOptions = {}) {
245
241
  if (def.default !== void 0)
246
242
  parts.push(`default=${JSON.stringify(def.default)}`);
247
243
  if (def.required) parts.push("required");
248
- if (def.type === "array" && def.options)
249
- parts.push(`options: ${def.options.join(", ")}`);
250
244
  relinka("log", parts.filter(Boolean).join(" | "));
251
245
  }
252
246
  }
253
247
  }
254
248
  export async function runMain(command, parserOptions = {}) {
255
- if (typeof command.onLauncherStart === "function")
256
- await command.onLauncherStart();
249
+ if (typeof command.onLauncherInit === "function")
250
+ await command.onLauncherInit();
257
251
  try {
258
252
  if (!parserOptions.fileBasedCmds && !command.commands) {
259
253
  let callerDir = process.cwd();
@@ -430,8 +424,8 @@ This can cause recursion or unexpected behavior.`
430
424
  }
431
425
  await relinkaShutdown();
432
426
  } finally {
433
- if (typeof command.onLauncherEnd === "function")
434
- await command.onLauncherEnd();
427
+ if (typeof command.onLauncherExit === "function")
428
+ await command.onLauncherExit();
435
429
  }
436
430
  }
437
431
  function checkHelp(argv) {
@@ -583,8 +577,8 @@ async function runCommandWithArgs(command, argv, parserOptions, returnCtx) {
583
577
  const def = command.args?.[key];
584
578
  const val = leftoverPositionals[i];
585
579
  if (val == null && def.required) {
586
- relinka("error", `Missing required positional argument: <${key}>`);
587
580
  await showUsage(command, parserOptions);
581
+ relinka("error", `Missing required positional argument: <${key}>`);
588
582
  if (autoExit) process.exit(1);
589
583
  else throw new Error(`Missing required positional argument: <${key}>`);
590
584
  }
@@ -601,8 +595,8 @@ async function runCommandWithArgs(command, argv, parserOptions, returnCtx) {
601
595
  }
602
596
  const valueOrDefault = rawVal ?? defaultMap[key];
603
597
  if (valueOrDefault == null && def.required) {
604
- relinka("error", `Missing required argument: --${key}`);
605
598
  await showUsage(command, parserOptions);
599
+ relinka("error", `Missing required argument: --${key}`);
606
600
  if (autoExit) process.exit(1);
607
601
  else throw new Error(`Missing required argument: --${key}`);
608
602
  }
@@ -612,17 +606,6 @@ async function runCommandWithArgs(command, argv, parserOptions, returnCtx) {
612
606
  } else {
613
607
  finalArgs[key] = castArgValue(def, rawVal, key);
614
608
  }
615
- if (def.type === "array" && def.options && finalArgs[key]) {
616
- const values = finalArgs[key];
617
- const invalidOptions = values.filter(
618
- (v) => def.options && !def.options.includes(v)
619
- );
620
- if (invalidOptions.length > 0) {
621
- throw new Error(
622
- `Invalid choice(s) for --${key}: ${invalidOptions.join(", ")}. Allowed options: ${def.options.join(", ")}`
623
- );
624
- }
625
- }
626
609
  } catch (err) {
627
610
  relinka("error", String(err));
628
611
  if (autoExit) process.exit(1);
@@ -647,8 +630,8 @@ async function runCommandWithArgs(command, argv, parserOptions, returnCtx) {
647
630
  }
648
631
  const cmdName = command.meta?.name || "unknown";
649
632
  const attempted = argv.length > 0 ? argv.join(" ") : "(no arguments)";
650
- relinka("error", `Unknown command or arguments: ${attempted}`);
651
633
  await showUsage(command, parserOptions);
634
+ relinka("error", `Unknown command or arguments: ${attempted}`);
652
635
  if (autoExit) {
653
636
  process.exit(1);
654
637
  } else {
@@ -692,7 +675,40 @@ function castArgValue(def, rawVal, argName) {
692
675
  return String(rawVal);
693
676
  case "array": {
694
677
  const arrVal = Array.isArray(rawVal) ? rawVal : [String(rawVal)];
695
- return arrVal.map(String);
678
+ const result = [];
679
+ const arrValStr = arrVal.map(String);
680
+ let warned = false;
681
+ for (let v of arrValStr) {
682
+ if (!warned && (v.startsWith("[") && !v.endsWith("]") || !v.startsWith("[") && v.endsWith("]"))) {
683
+ relinka("error", `Don't use quotes around array elements.`);
684
+ relinka(
685
+ "error",
686
+ `Also \u2014 don't use spaces \u2014 unless you wrap the whole array in quotes.`
687
+ );
688
+ relinka(
689
+ "warn",
690
+ `Array argument --${argName}: Detected possible shell splitting of bracketed value ('${v}').`
691
+ );
692
+ relinka(
693
+ "warn",
694
+ `If you intended to pass a bracketed list, quote the whole value like: --${argName} "[a, b, c]"`
695
+ );
696
+ }
697
+ warned = true;
698
+ if (v.startsWith("[") && v.endsWith("]")) {
699
+ v = v.slice(1, -1);
700
+ }
701
+ const parts = v.split(/\s*,\s*/).filter(Boolean);
702
+ parts.forEach((p) => {
703
+ if (p.startsWith('"') && p.endsWith('"') || p.startsWith("'") && p.endsWith("'")) {
704
+ throw new Error(
705
+ `Array argument --${argName}: Quoted values are not supported due to shell parsing limitations. Please avoid using single or double quotes around array elements.`
706
+ );
707
+ }
708
+ });
709
+ result.push(...parts);
710
+ }
711
+ return result;
696
712
  }
697
713
  default:
698
714
  return rawVal;
@@ -757,17 +773,15 @@ export async function runCmd(command, argv = [], parserOptions = {}) {
757
773
  if (valueOrDefault == null && def.required) {
758
774
  throw new Error(`Missing required argument: --${key}`);
759
775
  }
760
- finalArgs[key] = castArgValue(def, rawVal, key);
761
- if (def.type === "array" && def.options && finalArgs[key]) {
762
- const values = finalArgs[key];
763
- const invalidOptions = values.filter(
764
- (v) => def.options && !def.options.includes(v)
765
- );
766
- if (invalidOptions.length > 0) {
767
- throw new Error(
768
- `Invalid choice(s) for --${key}: ${invalidOptions.join(", ")}. Allowed options: ${def.options.join(", ")}`
769
- );
776
+ try {
777
+ if (def.type === "boolean") {
778
+ finalArgs[key] = rawVal !== void 0 ? castArgValue(def, rawVal, key) : false;
779
+ } else {
780
+ finalArgs[key] = castArgValue(def, rawVal, key);
770
781
  }
782
+ } catch (err) {
783
+ relinka("error", String(err));
784
+ throw err;
771
785
  }
772
786
  }
773
787
  const ctx = {
package/package.json CHANGED
@@ -28,7 +28,7 @@
28
28
  "license": "MIT",
29
29
  "name": "@reliverse/rempts",
30
30
  "type": "module",
31
- "version": "1.7.7",
31
+ "version": "1.7.8",
32
32
  "author": "reliverse",
33
33
  "bugs": {
34
34
  "email": "blefnk@gmail.com",